[...]是否有可能檢查一個對象是否實際上正在觀察該屬性 屬性?
號當志願打交道,你應該始終牢記以下模型:
當建立一個觀察你是負責清除,準確的觀察。觀察是通過它的上下文來確定的 - 因此,上下文必須是獨特的。當接收到通知時(並且在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