创建一个Objective-C对象,该对象使用相同的接口包装另一个对象-KVC/KVO问题

创建一个Objective-C对象,该对象使用相同的接口包装另一个对象-KVC/KVO问题,objective-c,key-value-coding,message-forwarding,Objective C,Key Value Coding,Message Forwarding,我需要在一个类层次结构中创建一个对象,从另一个类层次结构包装一个对象。它们都有非常相似的接口,我想让我的包装器自动将它无法识别的消息转发给它的目标,而不是实现它自己的属性。我用这样的东西来实现这个: - (id)forwardingTargetForSelector:(SEL)sel { if ([self.wrappedObject respondsToSelector:sel]) return self.wrappedObject; return self

我需要在一个类层次结构中创建一个对象,从另一个类层次结构包装一个对象。它们都有非常相似的接口,我想让我的包装器自动将它无法识别的消息转发给它的目标,而不是实现它自己的属性。我用这样的东西来实现这个:

- (id)forwardingTargetForSelector:(SEL)sel { if ([self.wrappedObject respondsToSelector:sel]) return self.wrappedObject; return self; } -(id)转发目标供选择人:(SEL)SEL { if([self.wrappedObject respondsToSelector:sel]) 返回self.wrappedObject; 回归自我; }
但这不适用于键值编码。如何让包装器以使用其包装对象属性的方式实现键值编码?

您必须覆盖
valueForKey:
setValue:forKey:
。例如:

- (id)valueForKey:(NSString *)key {
  if (/* wrapped object has key */)
    return [self.wrappedObject valueForKey: key];
  else
    return [super valueForKey: key];
}
棘手的部分是确定包裹对象实现的关键点。简单的方法是硬编码,但这并不太好。如果您希望非常通用,可以使用Objective-C的反射API进行操作。以下是两个想法:

  • 您的所有属性实际上都是声明的属性。您可以使用运行时函数类_getProperty来检查它是否存在,并可以选择提取其他信息。检查结果可能如下:
    if(class_getProperty([self.wrappedObject class],[key UTF8String])!=nil){…}

  • 您的属性也只能有访问器。然后,您应该从键构造选择器,并像以前一样使用
    [self.wrappedObject respondsToSelector:…]
    。getter的名称是键加冒号。但是,问题是具有不同getter/setter名称的属性。第一种选择肯定是最好的


太好了,谢谢你的提示!我们的项目目前正在远离这种方法,但我以后可能不得不使用这种解决方案。非常感谢。