深入理解 KVC\KVO 實現機制 — KVO


KVC和KVO都屬於鍵值編程而且底層實現機制都是isa-swizzing,所以本來想放在一起講的。但是篇幅有限所以就分成了兩篇博文。 KVC實現機制傳送門

KVO概述

鍵值觀察Key-Value-Observer就是觀察者模式。

  • 觀察者模式的定義:一個目標對象管理所有依賴於它的觀察者對象,並在它自身的狀態改變時主動通知觀察者對象。這個主動通知通常是通過調用各觀察者對象所提供的接口方法來實現的。觀察者模式較完美地將目標對象與觀察者對象解耦。

當需要檢測其他類的屬性值變化,但又不想被觀察的類知道,有點像FBI監視嫌疑人,這個時候就可以使用KVO了。

KVO同KVC一樣都依賴於Runtime的動態機制

KVO實現步驟

  • 注冊
//keyPath就是要觀察的屬性值
//options給你觀察鍵值變化的選擇
//context方便傳輸你需要的數據
-(void)addObserver:(NSObject *)anObserver 
        forKeyPath:(NSString *)keyPath 
           options:(NSKeyValueObservingOptions)options 
           context:(void *)context
  • 實現方法
//change里存儲了一些變化的數據,比如變化前的數據,變化后的數據;如果注冊時context不為空,這里context就能接收到。
-(void)observeValueForKeyPath:(NSString *)keyPath 
                     ofObject:(id)object
                       change:(NSDictionary *)change 
                      context:(void *)context
  • 移除
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

KVO的實現分析

使用觀察者模式需要被觀察者的配合,當被觀察者的狀態發生變化的時候通過事先定義好的接口(協議)通知觀察者。在KVO的使用中我們並不需要向被觀察者添加額外的代碼,就能在被觀察的屬性變化的時候得到通知,這個功能是如何實現的呢?同KVC一樣依賴於強大的Runtime機制。

系統實現KVO有以下幾個步驟:

  • 當類A的對象第一次被觀察的時候,系統會在運行期動態創建類A的派生類。我們稱為B。
  • 在派生類B中重寫類A的setter方法,B類在被重寫的setter方法中實現通知機制。
  • 類B重寫會 class方法,將自己偽裝成類A。類B還會重寫dealloc方法釋放資源。
  • 系統將所有指向類A對象的isa指針指向類B的對象。

KVO同KVC一樣,通過 isa-swizzling 技術來實現。當觀察者被注冊為一個對象的屬性的觀察對象的isa指針被修改,指向一個中間類,而不是在真實的類。其結果是,isa指針的值並不一定反映實例的實際類。

所以不能依靠isa指針來確定對象是否是一個類的成員。應該使用class方法來確定對象實例的類。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM