当使用addObserver:forKeyPath:options:context:
观察对象上的值时,最终需要调用该对象上的removeObserver:forKeyPath:
,以便稍后进行清理.但在这样做之前,是否可以判断一个对象是否真的在观察该属性?
我试图在我的代码中确保一个对象只在需要的时候移除一个观察者,但在某些情况下,观察者可能会try 两次移除自己.我正在努力防止这种情况发生,但以防万一,我只是想弄清楚是否有办法首先判断我的代码是否真的是某个观察者.
当使用addObserver:forKeyPath:options:context:
观察对象上的值时,最终需要调用该对象上的removeObserver:forKeyPath:
,以便稍后进行清理.但在这样做之前,是否可以判断一个对象是否真的在观察该属性?
我试图在我的代码中确保一个对象只在需要的时候移除一个观察者,但在某些情况下,观察者可能会try 两次移除自己.我正在努力防止这种情况发生,但以防万一,我只是想弄清楚是否有办法首先判断我的代码是否真的是某个观察者.
[...] 有没有可能判断一个物体是否真的观察到了这一点
不可以.在处理KVO时,您应该始终记住以下模型:
当建立观察时,你有责任删除该精确观察.一个观察结果是通过其上下文来识别的,因此,上下文必须是唯一的.在接收通知时(在Lion中,在移除观察者时),应该始终测试上下文,而不是路径.
处理观察对象的最佳实践是,在观察对象的设定器中移除并建立观察:
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,所以一定要在回调中判断上下文.
我想指出的最后一个问题是:观察到的属性必须符合KVO.You can't just observe anything