KVO – 如何检查对象是否是观察者?

当使用addObserver:forKeyPath:options:context:观察对象上的值时,最终您需要在该对象上调用removeObserver:forKeyPath:稍后进行清理。 在这之前,虽然,是否有可能检查一个对象实际上是否正在观察该属性?

我试图确保在我的代码中,一个对象只在需要的时候被删除,但是在某些情况下,观察者可能会尝试删除两次。 我正在努力防止这种情况,但为了以防万一,我一直在试图弄清楚是否有办法检查我的代码实际上是否是某个事物的观察者。

[…]是否有可能检查一个对象实际上是否在观察该属性?

不。在处理KVO时,您应始终注意以下模式:

在build立观察时,您有责任去除确切的观察结果。 一个观察是由它的上下文来确定的 – 因此,上下文必须是独一无二的。 当接收到通知(并且在Lion中,当移除观察者时),您应该始终testing上下文,而不是path。

处理被观察物体的最佳实践是去除和build立被观察物体的观察者:

 static int fooObservanceContext; - (void)setFoo:(Foo *)foo { [_foo removeObserver:self forKeyPath:@"bar" context:&fooObservanceContext]; _foo = foo; // or whatever ownership handling is needed. [foo addObserver:self forKeyPath:@"bar" options:0 context:&fooObservanceContext]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == &fooObservanceContext) { // handle change } else { // not my observer callback [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } - (void)dealloc { self.foo = nil; // removes observer } 

当使用KVO时,只要观察到位,就必须确保观察者和观察者都是活的。

在添加观测数据时,您必须平衡这一点,只需要移除相同的观测数据。 不要假设,你是唯一使用KVO的人。 框架类可能会将KVO用于自己的目的,因此请始终检查callback中的上下文。

我想指出的最后一个问题是:观察到的属性必须符合KVO。 你不能只观察任何东西 。

部分NSKeyValueObserving协议是这样的:

  - (void *)observationInfo 

应该列出观察员。

编辑仅用于debugging。