[...]是否有可能检查一个对象是否实际上正在观察该属性 属性?
号当志愿打交道,你应该始终牢记以下模型:
当建立一个观察你是负责清除,准确的观察。观察是通过它的上下文来确定的 - 因此,上下文必须是独特的。当接收到通知时(并且在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
}
当使用志愿,你必须确保这两个对象,观察者和observee,只要观察到位,他们就活着。
当添加一个观察,你必须平衡这与一个删除相同的观察。不要假设,你是唯一使用KVO的人。框架类可能会将KVO用于自己的目的,因此请始终检查回调中的上下文。
我想指出的最后一个问题:观察到的属性必须符合KVO。 You can't just observe anything。
KVO,因为它有一个相当粗糙的API。有些库可以简化它的使用,甚至允许你为了方便而使用块。详情请查阅http://thirdcog.eu/pwcblocks/#goodies。我也有我自己的实现能够自动删除观察员,当任何对象被释放。它尚未在实际应用中进行过测试,但您可能还是要仔细看看。在GitHub上搜索'tastykvo'。 – 2012-02-10 17:46:33