簡介: KVO的全稱是Key-Value Observing , 翻譯過來就是鍵值監聽,可以用於監聽某個對象屬性值的改變。
常用API :
1: 添加觀察者: addObserve:forKeyPatch:option:context:
2:實現觀察相應方法: observeValueForKeyPath:ofObject:change:context
3:在觀察者釋放之前移除對象上的監聽: removeObserver:forKeyPath:
關聯監聽:
// .h 中有一個 fullName 屬性, 他是有其他兩個屬性組成的, _firstName、 _lastName 他兩的變化影響着 fullName 最終結果。 所以 + (NSSet*) keyPathsForValuesAffectingFullName 方法可以吧相關聯屬性添加進去,
- (NSString*)fullName {
return [NSString stringWithFormat:@"%@ %@", _firstName, _lastName];
}
+ (NSSet*) keyPathsForValuesAffectingFullName
{
return [NSSet setWithObjects:@"lastName", @"firstName", nil];
}
自動/手動監聽
+ (BOOL) automaticallyNotifiesObserversOfSteps {
return NO;
}
監聽對象中如果設置爲No, 那麼將會關閉自動監聽,如果要使用手動監聽,那麼:
[_p willChangeValueForKey:@"被觀察屬性"];
_p.被觀察屬性 = 新值
[_p didChangeValueForKey:@"被觀察屬性"];
KVO 原理
如圖:
* 未被觀察的對象: 它的實例對象isa 指針指向他的類對象,從他的類對象緩存和方法列表中尋找方法實現。
* 被觀察的對象 :在添加觀察者的時候動態生成了一個類NSKVONotifying_Class 並且 被觀察類的實例對象 把isa指針指向了動態生成的這個類。當實例調用方法的時候調用了NSKVONotifying_Class 子類的方法,方法實現調用了foundation 框架中_NSSetIntValueAndNotify 方法,set方法只要做了兩件事 1.改變父類的值 2.然後通知.
* removeObserver:forKeyPath 移除觀察者其實就是類對象把他的isa 指正指向他的類對象,