创建一个将另一个对象与相同接口包装的对象-KVC/KVO问题
-
01-10-2019 - |
题
我需要在一个类层次结构中创建一个对象,该对象从另一个对象中包裹一个对象。它们都有非常相似的界面,我想自动拥有我的包装器向前消息,它不识别其目标而代替实施自己的属性。我使用这样的东西让这个工作:
- (id)forwardingTargetForSelector:(SEL)sel { if ([self.wrappedObject respondsToSelector:sel]) return self.wrappedObject; return self; }
但这对于键值编码不起作用。我该如何以使用其包装对象的属性的方式让包装器实现键值编码?
解决方案
你必须覆盖 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进行操作。这是两个想法:
您所有的属性实际上都是声明的属性。 您可以使用运行时函数class_getProperty检查其存在并选择提取其他信息。然后检查可能看起来像这样:
if (class_getProperty([self.wrappedObject class], [key UTF8String]) != nil) {...}
.您的属性也可能只有登录器。 然后,您应该从密钥中构造选择器并使用
[self.wrappedObject respondsToSelector: ...]
就像您以前一样。 Getter的名字是钥匙和结肠。但是,此问题是具有不同getter/setter名称的属性。第一个选择绝对是最好的。
不隶属于 StackOverflow