KVC、KVO實現過程

滴水微瀾發表於2017-06-06

 

1.KVC的實現過程

以 [object setValue:@"134567" forKey:@"uid"];為例子,來探究KVC的實現過程

第一步:搜尋
1、首先搜尋setKey:方法.(key指成員變數名, 首字母大寫)
2、上面的setter方法沒找到, 如果類方法accessInstanceVariablesDirectly返回YES. 那麼按 _key, _isKey,key, iskey的順序搜尋成員名.(NSKeyValueCodingCatogery中實現的類方法, 預設實現為返回YES)
3、如果沒有找到成員變數, 呼叫setValue:forUnderfinedKey:

第二步:編譯器處理
被編譯器處理後:
// 首先找到對應sel
SEL sel = sel_get_uid("setValue:forKey:");
// 根據object->isa找到sel對應的IMP實現指標
IMP method = objc_msg_lookup (object->isa,sel);
// 呼叫指標完成KVC賦值
method(object, sel, @"134567", @"uid");

解釋:
1.先根據方法名通過C函式sel_get_uid拿到選擇子sel
2.使用C函式objc_msg_lookup通過物件指標,選擇子獲取函式實現指標
3. 呼叫C函式method(object, sel, @"134567", @"uid"),實現KVC賦值

2.KVO的實現過程

第一步:呼叫KVC方法
KVO若有起作用,首先要先呼叫KVC方法:
[self.object addObserver:self forKeyPath:@"uid" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];

第二步:實現KVO後,系統相應的處理
系統實現KVO有以下幾個步驟:
1.當類A的物件第一次被觀察的時候,系統會利用執行時動態建立與類A一樣的NSKVONotifying_A派生類, 並且只有1個屬性的get, set方法實現.
2.在派生類NSKVONotifying_A中重寫類A的setter方法,NSKVONotifying_A類在被重寫的setter方法中實現通知機制。
3.類NSKVONotifying_A重寫會 class方法,將自己偽裝成類A。類NSKVONotifying_A還會重寫dealloc方法釋放資源。
4.系統將所有指向類A物件的isa指標指向類NSKVONotifying_A的物件。

 

參考文章:
KVC, KVO 實現原理:http://www.cnblogs.com/MrTao/p/5825457.html

相關文章