Hea*_*ers 5 c objective-c objective-c-runtime
我NSManagedObject在单元测试中创建了一堆简单的s.它们只有一个name类型的属性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
Run Code Online (Sandbox Code Playgroud)
既然foo是一个ivar,我认为我应该能够写一个宏来获取foo(Foo)的类型,并用来创建我的Foo:
#define InsertManagedObjectByVariable(variable) \
do { \
variable = [NSEntityDescription insertNewObjectForEntityName:NSStringFromClass([typeof(variable) class])]; \
variable.name = (NSString *) CFSTR(#variable);
} while(0)
Run Code Online (Sandbox Code Playgroud)
但是,这会在clang中导致以下警告:
variable = [NSEntityDescription insertNewObjectForEntityName:NSStringFromClass([typeof(variable) class])];
^
Expected expression
Run Code Online (Sandbox Code Playgroud)
我还以为我可以尝试确定使用Objective-C的运行时类型IVar的Ivar class_getInstanceVariable(Class cls, const char* name),但唯一IVar可以从类型编码类型的信息由ivar_getTypeEncoding是id,这是不够的.
有人可以想到IVar一种在编译时或运行时获取类型信息的方法吗?
我没有尝试从ivar获取类信息,但我知道@property声明会对类的信息进行编码.例如,这个属性声明:
@property (copy) NSString *normalString;
Run Code Online (Sandbox Code Playgroud)
在运行时生成此属性字符串(使用property_getAttributes()检索):
T@"NSString",C,VnormalString
Run Code Online (Sandbox Code Playgroud)
我已经为这些信息编写了一些开源解析代码.
获得类名后,可以使用NSClassFromString()将其转换为实际的Class对象,并从那里发送结果.
免责声明:这可能不应该依赖于生产应用程序,因为它没有文档记录.
安id是一个id.在运行时,所有Objective-C对象都具有相同的类型(objc_object).这与ObjC的动态性质有关.例如,对象可以在运行时更改类,可以创建新类,并且可以更改类层次结构.您可以询问特定实例的类型(因为它存储在其中objc_object),但指向对象的指针只是指向对象的指针.甚至还不到:它实际上只是一个指向C结构的指针,它恰好在末尾分配了额外的内存(用于保存子类ivars).
您的宏似乎很有趣,但您可能需要将类名作为第二个参数传递而不是自动检测它.