OC 觀察者模式(通知中心,KVO) 什麼是觀察者模式??? A對B的變化感興趣,就註冊為B的觀察者,當B發生變化時通知A,告知B發生了變化。這就是觀察者模式。 觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態上發生變化時,會通知所有觀察者對象,使它們 ...
OC 觀察者模式(通知中心,KVO)
什麼是觀察者模式???
A對B的變化感興趣,就註冊為B的觀察者,當B發生變化時通知A,告知B發生了變化。這就是觀察者模式。
觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態上發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己或者做出相應的一些動作。在IOS開發中我們接觸到觀察者模式的實現方式有NSNotificationCenter、KVO等.
通知中心
以NSNotificationCenter為中心,觀察者往Center中註冊對某個主題對象的變化感興趣,主題對象通過NSNotificationCenter進行變化廣播。所有的觀察和監聽行為都向同一個中心註冊,所有對象的變化也都通過同一個中心向外廣播。
通知中心執行順序
- 通過NSNotificationCenter的addObserver:selector:name:object介面來註冊通知中心.
- 被觀察的對象,通過postNotificationName:object:userInfo:向通知中心發送某一類型通知.
- 當有通知來的時候,Center會調用觀察者註冊的介面來廣播通知,同時傳遞存儲著更改內容的NSNotification對象.
- 當該通知不再使用時,可以在dealloc方法里removeObserver:刪除觀察者.
KVO鍵值觀察
這是一個典型的觀察者模式,觀察者在鍵值改變時會得到通知.
NSKeyValueObserving非正式協議定義了一種機制,它允許對象去監聽其它對象的某個屬性的修改.NSObject提供了一個NSKeyValueObserving協議的預設實現,它為所有對象提供了一種自動發送修改通知的能力.我們可以通過禁用自動發送通知並使用這個協議提供的方法來手動實現通知的發送,以便更精確地去處理通知.
KVO的使用步驟
- 註冊需要觀察的對象的屬性addObserver:forKeyPath:options:context:.
- 實現observeValueForKeyPath:ofObject:change:context:方法,這個方法當觀察的屬性變化時會自動調用.在這個方法中還通過NSKeyValueObservingOptionNew這個參數要求把新值在dictionary中傳遞過來.
- 取消註冊觀察removeObserver:forKeyPath:context:.
手動設置KVO
//關閉某key值的KVO
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
BOOL automatic = YES;
if ([key isEqualToString:@"age"]) {
automatic = NO;
} else {
automatic = [super automaticallyNotifiesObserversForKey:key];
}
return automatic;
}
//重寫setter方法手動設置KVO
- (void)setAge:(int)age {
//手動設置KVO
if (_age != age) {
[self willChangeValueForKey:@"age"];
_age = age;
[self didChangeValueForKey:@"age"];
}
}
KVO的實現原理
當某一個類的實例第一次使用KVO的時候,系統就會在運行期間動態的創建該類的一個派生類,該類的命名規則一般是以NSKVONotifying為首碼,以原本的類名為尾碼。並且將原型的對象的isa指針指向該派生類。同時在派生類中重載了使用KVO的屬性的setter方法,在重載的setter方法中實現真正的通知機制,正如前面我們手動實現KVO一樣。這麼做是基於設置屬性會調用 setter 方法,而通過重寫就獲得了 KVO 需要的通知機制。當然前提是要通過遵循 KVO 的屬性設置方式來變更屬性值,如果僅是直接修改屬性對應的成員變數,是無法實現 KVO 的。