5

NSManagedObject我在单元测试中创建了一堆简单的 s。它们只有一个nametype 属性NSString *。我总是给我NSManagedObject相同的entityName名字Class

我想避免编写以下代码 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,我认为我应该能够编写一个宏来获取foo( Foo) 的类型,并使用它来创建我的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

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

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

4

3 回答 3

7

我没有尝试从 ivar 获取类信息,但我知道@property声明确实编码了关于类的信息。例如,这个属性声明:

@property (copy) NSString *normalString;

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

T@"NSString",C,VnormalString

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

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

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

于 2012-06-29T20:52:25.060 回答
5

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

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

于 2012-06-29T17:34:03.843 回答
0

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

喜欢:

NSString *aString = @"random string";
NSLog(@"%@",NSStringFromClass([aString class]));
于 2012-06-29T17:22:35.907 回答