IOS-詳解KVO底層實現

1、KVO (Key-Value Observing)

KVO 是 Objective-C 對觀察者模式(Observer Pattern)的實現。也是 Cocoa Binding 的基礎。當被觀察對象的某個屬性發生更改時,觀察者對象會得到通知。ui

有意思的是,你不須要給被觀察的對象添加任何額外代碼,就能使用 KVO 。這是怎麼作到的?指針

2、 KVO內部實現原理

  • KVO是基於runtime機制實現的
  • 當某個類的屬性對象第一次被觀察時,系統就會在運行期動態地建立該類的一個派生類,在這個派生類中重寫基類中任何被觀察屬性的setter 方法。派生類在被重寫的setter方法內實現真正的通知機制
  • 若是原類爲Person,那麼生成的派生類名爲NSKVONotifying_Person
  • 每一個類對象中都有一個isa指針指向當前類,當一個類對象的第一次被觀察,那麼系統會偷偷將isa指針指向動態生成的派生類,從而在給被監控屬性賦值時執行的是派生類的setter方法
  • 鍵值觀察通知依賴於NSObject 的兩個方法: willChangeValueForKey:didChangevlueForKey:;在一個被觀察屬性發生改變以前, willChangeValueForKey:必定會被調用,這就 會記錄舊的值。而當改變發生後,didChangeValueForKey:會被調用,繼而 observeValueForKey:ofObject:change:context: 也會被調用。
  • 補充:KVO的這套實現機制中蘋果還偷偷重寫了class方法,讓咱們誤認爲仍是使用的當前類,從而達到隱藏生成的派生類code

 

3、補充: 如何關閉默認的KVO的默認實現,並進入自定義的KVO實現?(看連接)

4、附註: KVC底層實現原理(以下)

KVC運用了一個isa-swizzling技術. isa-swizzling就是類型混合指針機制, 將2個對象的isa指針互相調換, 就是俗稱的黑魔法.
KVC主要經過isa-swizzling, 來實現其內部查找定位的. 默認的實現方法�由NSOject提供isa指針, 如其名稱所指,(就是is a kind of的意思), 指向分發表對象的類. 該分發表實際上包含了指向實現類中的方法的指針, 和其它數據。server

  • 具體主要分爲三大步
  • 第一步:尋找該屬性有沒有setsetter方法?有,就直接賦值
  • 第二步:尋找有沒有該屬性帶下劃線的成員屬性?有,就直接賦值
  • 第三步:尋找有沒有該屬性的成員屬性?有,就直接賦值
  • 或者這麼說
  • 一、首先搜索setKey:方法.(key指成員變量名, 首字母大寫)
  • 二、上面的setter方法沒找到, 若是類方法accessInstanceVariablesDirectly返回YES. 那麼按 _key, _isKey,key, iskey的順序搜索成員名.(NSKeyValueCodingCatogery中實現的類方法, 默認實現爲返回YES)
  • 三、若是沒有找到成員變量, 調用setValue:forUnderfinedKey:

好比說以下的一行KVC的代碼:對象

  • 舉個🌰e.g:

[object setValue:@"13123" forKey:@"uuid"];

就會被編譯器處理成:
// 首先找到對應sel
SEL sel = sel_get_ uuid("setValue:forKey:");
// 根據object->isa找到sel對應的IMP實現指針
IMP method = objc_msg_lookup (object->isa,sel);
// 調用指針完成KVC賦值
method(object, sel, @"13123", @"uuid");
做者:Mg明明就是你 連接:https://www.jianshu.com/p/829864680648 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
做者:Mg明明就是你 連接:https://www.jianshu.com/p/829864680648 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索