KVC/KVO实现原理分析
2019獨角獸企業重金招聘Python工程師標準>>>
1. 函數調用(消息)實現分析:
我們看這條語句:
[代碼]c#/cpp/oc代碼:
| 1 | [self.person setValue:@"Vincent"forKey:@"name"]; |
就會被編譯器處理成:
[代碼]c#/cpp/oc代碼:
| 1 | SEL sel = sel_get_uid ("setValue:forKey:"); |
| 2 | ? |
| 3 | IMP method = objc_msg_lookup (self.person->isa,sel); |
| 4 | ? |
| 5 | method(self.person, sel,@"Vincent",@"name"); |
也就是說iOS中函數調用并不是被靜態編譯為地址調用,而是被轉為查表、調用!
2. 這里需要介紹幾個基本概念:
(1). SEL數據類型:它是編譯器運行Objective-C里的方法的環境參數。
(2). IMP數據類型:他其實就是一個 編譯器內部實現時候的函數指針。當Objective-C編譯器去處理實現一個方法的時候,就會指向一個IMP對象,這個對象是C語言表述的類型(事實上,在Objective-C的編譯器處理的時候,基本上都是C語言的)。
(3). isa指針,如其名稱所指,(就是is a kind of的意思),指向維護分發表的對象的類。該分發表實際上包含了指向實現類中的方法的指針,和其它數據。
3.? KVO/KVC實現分析:
當我們為一個類的某個屬性添加observer時候,框架自動創建這個類的一個子類,并且修改這個類的isa指向這個新的子類。
由于在ios中函數調用都是轉化為isa查表形式,所以這次查得時新的子類的表,
也就是說對類的函數調用被子類給攔截了,在攔截的實現中就可以通知observer了。
修改類的isa被稱為isa-swizzling技術。isa-swizzling就是類型混合指針機制。KVC主要通過isa-swizzling,來實現其內部查找定位的。
比如還是這段代碼:? ?
[代碼]c#/cpp/oc代碼:
| 1 | [self.person setValue:@"Vincent"forKey:@"name"]; |
它會被編譯為:
[代碼]c#/cpp/oc代碼:
| 1 | SEL sel = sel_get_uid ("setValue:forKey:"); |
| 2 | ? |
| 3 | IMP method = objc_msg_lookup (self.person->isa,sel); |
| 4 | ? |
| 5 | method(self.person, sel,@"Vincent",@"name"); |
這里的isa是動態生成的子類,你debugger調試一個被觀察的類就會發現它的isa已經發生了變化!而沒有被觀察的類的isa是正常的,如圖所示:
也就是說我們調用setValue...的時候實際上已經調用observer的didChangeValueForKey:方法!
因為KVC的實現機制,可以很容易看到某個KVC操作的Key,而后也很容易的跟觀察者注冊表中的Key進行匹對。假如訪問的Key是被觀察的Key,那么我們在內部就可以很容易的到觀察者注冊表中去找到觀察者對象,而后給他發送消息。
轉載于:https://my.oschina.net/u/1782374/blog/376211
總結
以上是生活随笔為你收集整理的KVC/KVO实现原理分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: InputStreamReader 和
- 下一篇: c++构造函数详解(转)