? ? ? ?KVO機制不像通知機制那樣通過一個通知中心通知所有觀察者對象,而是在對象屬性變化時通知會被直接發送給觀察者的對象。圖1為KVO機制解析圖。
圖1:KVO機制圖
? ? ? ?可以看到,屬性發生變化的對象需要發出消息addObserver:forKeyPath:options:context:給注冊觀察者,使觀察者關注它的某個屬性的變化。當對象屬性變化時,觀察者就會接收到通知,觀察者需要重寫方法observeValueForKeyPath:ofObject:change:context:以響應屬性的變化。
? ? ? ?下面我們來看一個實際的案例,我們使用KVO機制來監視應用程序的狀態變化。應用程序委托對象AppDelegate的appStatus屬性是要觀察的屬性。AppDelegate的代碼如下:
? ? ? ?上述代碼中第①行的appStatus屬性是需要觀察的屬性,在Swift版中它的定義上必須要加dynamic,以表示該屬性是在運行時動態派發的。第②行代碼用于定義觀察者AppStatusObserver,AppStatusObserver是我們的自定義類,它負責觀察appStatus屬性的變化。第③行代碼用于創建AppStatusObserver對象。
? ? ? ?第④行代碼是關鍵,addObserver:forKeyPath:options:context:語句告訴觀察者(AppStatusObserver)開始觀察AppDelegate的appStatus屬性變化,其中參數addObserver是觀察者對象;forKeyPath是被關注對象的屬性;options是為屬性變化設置的選項,本例中New和Old表示把屬性新舊兩個值都傳遞給觀察者,這些值是NSKeyValueObservingOptions類型的成員;context參數是上下文內容,它的類型是C語言形式的任何指針類型,
Swift版表示為UnsafeMutablePointer
? ? ? ?觀察者AppStatusObserver的代碼如下:
? ? ? ?因為NSObject類實現了NSKeyValueObserving協議,所以只需聲明AppStatusObserver繼承了NSObject類,而無需實現NSKeyValueObserving協議。
? ? ? ?observeValueForKeyPath:ofObject:change:context: 方法的observeValueForKeyPath 參數是被關注的屬性。
? ? ? ?ofObject是被關注的對象,change是字典類型,包含了屬性變化的內容,這些內容與注冊時屬性變化設置的選項(options參數)有關。context是注冊時傳遞的上下文內容。
? ? ? ?第一次運行程序到界面時,會有兩個狀態的變化,日志結果如下:
? ? ? ?appStatus - launch
? ? ? ?appStatus - active
? ? ? ?如果將應用退到后臺,然后再回到前臺,日志結果如下:
? ? ? ?appStatus - inactive
? ? ? ?appStatus - background
? ? ? ?appStatus - inactive
? ? ? ?appStatus - active
? ? ? ?關于應用程序狀態變化相關的內容,百恒網絡在這里就不再解釋了。