NSProxy和关键价值观察

时间:2012-01-29 17:06:45

标签: objective-c cocoa key-value-observing nsproxy

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

1 个答案:

答案 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在上面的第一个声明中说的那样,所以这篇文章只是一个确认!请注意,他实际提出的第二个代理人不需要,你只需要自己跟踪观察者。