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

时间:2012-06-29 16:23:45

标签: objective-c c objective-c-runtime

我在单元测试中创建了一堆简单的NSManagedObject。他们只有一个name类型的NSString *属性。我总是给NSManagedObject entityNameClass这个名字。

我想避免编写以下代码30次以设置单元测试:

@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)的类型,并用来创建我的{{1 }}:

Foo

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

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

我还以为我可以尝试使用来自variable = [NSEntityDescription insertNewObjectForEntityName:NSStringFromClass([typeof(variable) class])]; ^ Expected expression 的objective-c运行时IVar来确定类型,但是{{1}中类型编码中唯一可用的Ivar class_getInstanceVariable(Class cls, const char* name)类型信息}}是IVar,这还不够。

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

3 个答案:

答案 0 :(得分:6)

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

@property (copy) NSString *normalString;

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

T@"NSString",C,VnormalString

我已为此信息撰写some open source parsing code

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

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:0)

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

像:

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