KVO的原理

KVO基本原理:

1.KVO是基于runtime機制實現(xiàn)的

2.當某個類的屬性對象第一次被觀察時,系統(tǒng)就會在運行期動態(tài)地創(chuàng)建該類的一個派生類,在這個派生類中重寫基類中任何被觀察屬性的setter 方法。派生類在被重寫的setter方法內實現(xiàn)真正的通知機制

3.如果原類為Person,那么生成的派生類名為NSKVONotifying_Person

4.每個類對象中都有一個isa指針指向當前類,當一個類對象的第一次被觀察,那么系統(tǒng)會偷偷將isa指針指向動態(tài)生成的派生類,從而在給被監(jiān)控屬性賦值時執(zhí)行的是派生類的setter方法

5.鍵值觀察通知依賴于NSObject 的兩個方法: willChangeValueForKey: 和 didChangevlueForKey:;在一個被觀察屬性發(fā)生改變之前, willChangeValueForKey:一定會被調用,這就 會記錄舊的值。而當改變發(fā)生后,didChangeValueForKey:會被調用,繼而 observeValueForKey:ofObject:change:context: 也會被調用。

KVO深入原理:

1.Apple 使用了 isa 混寫(isa-swizzling)來實現(xiàn) KVO 。當觀察對象A時,KVO機制動態(tài)創(chuàng)建一個新的名為:?NSKVONotifying_A的新類,該類繼承自對象A的本類,且KVO為NSKVONotifying_A重寫觀察屬性的setter?方法,setter?方法會負責在調用原?setter?方法之前和之后,通知所有觀察對象屬性值的更改情況。

2.NSKVONotifying_A類剖析:在這個過程,被觀察對象的 isa 指針從指向原來的A類,被KVO機制修改為指向系統(tǒng)新創(chuàng)建的子類 NSKVONotifying_A類,來實現(xiàn)當前類屬性值改變的監(jiān)聽;

3.所以當我們從應用層面上看來,完全沒有意識到有新的類出現(xiàn),這是系統(tǒng)“隱瞞”了對KVO的底層實現(xiàn)過程,讓我們誤以為還是原來的類。但是此時如果我們創(chuàng)建一個新的名為“NSKVONotifying_A”的類(),就會發(fā)現(xiàn)系統(tǒng)運行到注冊KVO的那段代碼時程序就崩潰,因為系統(tǒng)在注冊監(jiān)聽的時候動態(tài)創(chuàng)建了名為NSKVONotifying_A的中間類,并指向這個中間類了。

4.(isa 指針的作用:每個對象都有isa 指針,指向該對象的類,它告訴 Runtime 系統(tǒng)這個對象的類是什么。所以對象注冊為觀察者時,isa指針指向新子類,那么這個被觀察的對象就神奇地變成新子類的對象(或實例)了。)?因而在該對象上對 setter 的調用就會調用已重寫的 setter,從而激活鍵值通知機制。

5.子類setter方法剖析:KVO的鍵值觀察通知依賴于 NSObject 的兩個方法:willChangeValueForKey:和 didChangevlueForKey:,在存取數(shù)值的前后分別調用2個方法: 被觀察屬性發(fā)生改變之前,willChangeValueForKey:被調用,通知系統(tǒng)該 keyPath?的屬性值即將變更;當改變發(fā)生后, didChangeValueForKey: 被調用,通知系統(tǒng)該 keyPath?的屬性值已經變更;之后,?observeValueForKey:ofObject:change:context: 也會被調用。且重寫觀察屬性的setter?方法這種繼承方式的注入是在運行時而不是編譯時實現(xiàn)的。
1829339-77757288cc139f44.png

適用于:

1.一鍵換膚 首先創(chuàng)建一個皮膚單例類  然后所有的 頁面都通過kvo觀察單例類   當進行一鍵換膚時   更改單例類的屬性   所有的界面收到此事件的更改
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容