反映时:应设置属性还是直接设置值? (目标C)

时间:2009-09-06 21:54:54

标签: objective-c reflection properties xml-serialization

我正在为objective-c编写一个xml序列化类 关键是给类一个类类型和一个xml文件。 它应该返回一个包含数据的实例。

我已经完成了它,它确实有很多 - 处理原语(+ nsstring),用户定义的类和nsarray。不处理指针或C数组。
显然,这很大程度上依赖于反思。

问题:当我设置某个类的实例的值时,我应该检查是否存在具有正确名称的属性,还是可以使用简单的反射设置变量?

这是我到目前为止使用的那种代码:

id newClass = class_createInstance(NSClassFromString(elementName), sizeof(unsigned));
Ivar nameVar = class_getInstanceVariable([newClass class], "name");
if (nameVar != nil)
    object_setIvar(newClass, nameVar, [NSString stringWithString:@"George"]);

此外,在这种作业之后,我应该发布什么吗?

1 个答案:

答案 0 :(得分:6)

呃......你通常需要进入运行时才能完成代码所做的事情。以下功能完全正常,完全相同:

id newObject = [[NSClassFromString(elementName) alloc] init];
@try {
  [newObject setValue:@"George" forKey:@"name"];
@catch (NSException *e) {
  if ([[e name] isEqualToString:NSUndefinedKeyException]) {
    NSLog(@"%@ does not recognize the property \"name\"", elementName);
  }
}

//... do stuff with newObject
[newObject release];

如果你需要放入其他内容,比如浮点数或整数或结构,你可以将它们装入NSValue(或子类),然后将它们传递给setValue:forKey:。例如:

NSNumber * aFloat = [NSNumber numberWithFloat:42.0];
[newObject setValue:aFloat forKey:@"aFloatIvar"];

NSRect frame = NSMakeRect(0, 0, 42, 54);
NSValue * aStruct = [NSValue valueWithBytes:&frame objcType:@encode(NSRect)];
[newObject setValue:aStruct forKey:@"aStructIvar"];