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