NSProxy
似乎非常适合那些尚不存在的替代物。例如。
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
return [self.target methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation invokeWithTarget:self.target];
}
上面的代码将透明地将任何方法调用传递给代理所代表的目标。但是,它似乎没有处理目标上的KVO观察和通知。我试图使用NSProxy
子类代表要传递给NSTableView
的对象,但我收到以下错误。
Cannot update for observer <NSAutounbinderObservance 0x105889dd0> for
the key path "objectValue.status" from <NSTableCellView 0x105886a80>,
most likely because the value for the key "objectValue" has changed
without an appropriate KVO notification being sent. Check the
KVO-compliance of the NSTableCellView class.
有没有办法让符合KVO的透明NSProxy
?
答案 0 :(得分:1)
我没有OP完全相同的用例(没有绑定),但是我的情况类似:我正在创建一个NSProxy子类,它将自身呈现为实际从服务器加载的另一个对象。在加载期间,其他对象可以订阅代理,代理将在对象到达时转发KVO。
代理中有一个简单的NSArray
属性,用于记录所有观察者。在加载实际对象之前,代理会在nil
中返回valueForKey:
。当realObject
到达时,代理会在真实对象上调用addObserver:forKeyPath:options:context:
,然后通过运行时的魔力遍历realObject
的所有属性并执行此操作:
id old = object_getIvar(realObject, backingVar);
object_setIvar(realObject, backingVar, nil);
[realObject willChangeValueForKey:propertyName];
object_setIvar(realObject, backingVar, old);
[realObject didChangeValueForKey:propertyName];
这似乎有效,至少我还没有得到任何KVO合规性错误。它确实有意义,首先所有属性都是零,然后它们从零变为实际值。这就像ipmcc在上面的第一个声明中说的那样,所以这篇文章只是一个确认!请注意,他实际提出的第二个代理人不需要,你只需要自己跟踪观察者。