我如何获得ivar的Objective-C类?

我在unit testing中创建了一堆简单的NSManagedObject 。 它们只有一个NSString *类型的name属性。 我总是给我的NSManagedObject相同的entityNameClass名称。

我想避免编写以下代码30次来设置unit testing:

 @interface FooTest : GHTestCase { Foo *foo; } @end @implementation FooTest - (void) setUp { [super setUp]; foo = [NSEntityDescription insertNewObjectForEntityForName:@"Foo" inManagedObjectContext:managedObjectContext]; foo.name = @"foo"; } @end 

由于foo是一个ivar,我认为我应该能够写一个宏来获取fooFoo )的类型,并用来创建我的Foo

 #define InsertManagedObjectByVariable(variable) \ do { \ variable = [NSEntityDescription insertNewObjectForEntityName:NSStringFromClass([typeof(variable) class])]; \ variable.name = (NSString *) CFSTR(#variable); } while(0) 

但是,这会在clang中导致以下警告:

 variable = [NSEntityDescription insertNewObjectForEntityName:NSStringFromClass([typeof(variable) class])]; ^ Expected expression 

我还以为我可以尝试使用Ivar class_getInstanceVariable(Class cls, const char* name)的objective-c运行时IVar来确定类型,但是IVar类型编码中唯一可用的IVar类型信息是id ,这不是足够。

有人能想到一种在编译时或运行时获取IVar类型信息的方法吗?

我没有尝试从ivar获取类信息,但我知道@property声明会对该类的信息进行编码。 例如,这个属性声明:

 @property (copy) NSString *normalString; 

在运行时生成此属性字符串(使用property_getAttributes()检索):

 T@"NSString",C,VnormalString 

我已经为这些信息编写了一些开源解析代码 。

获得类名后,可以使用NSClassFromString()将其转换为实际的Class对象,并从那里发送结果。

免责声明:这可能不应该依赖于生产应用程序,因为它没有文档记录。

idid 。 在运行时,所有Objective-C对象都具有相同的类型( objc_object )。 这与ObjC的动态性质有关。 例如,对象可以在运行时更改类,可以创建新类,并且可以更改类层次结构。 您可以询问特定实例的类型(因为它存储在objc_object ),但指向对象的指针只是指向对象的指针。 甚至比这更少:它实际上只是指向C结构的指针,恰好在末尾分配了额外的内存(用于保存子类ivars)。

您的宏似乎很有趣,但您可能需要将类名作为第二个参数传递而不是自动检测它。

也许我误解了你想要实现的目标。 要获得iVar的类,你不能使用iVar的方法吗?

喜欢:

 NSString *aString = @"random string"; NSLog(@"%@",NSStringFromClass([aString class]));