cms網(wǎng)站建設(shè)有多少條數(shù)據(jù)正規(guī)的代運(yùn)營(yíng)公司
第11條:理解objc_msgSend的作用
1. 動(dòng)態(tài)語(yǔ)言特性
在Objective-C中,如果向某對(duì)象傳遞消息,那就會(huì)使用動(dòng)態(tài)綁定機(jī)制來(lái)決定需要調(diào)用的方法。在底層,所有方法都是普通的C語(yǔ)言函數(shù),然而對(duì)象收到消息之后,究竟該調(diào)用哪個(gè)方法則完全于運(yùn)行期決定,甚至可以在程序運(yùn)行時(shí)改變,這些特性使得Objective-C成為一門真正的動(dòng)態(tài)語(yǔ)言。
2. 消息派發(fā)(message dispatch)
*** 消息派發(fā)的一般過程 ***
給對(duì)象發(fā)送消息,如下:
id returnValue = [someObject messageName:parameter];
解釋:someObject是“接收者”,messageName是“選擇器”,選擇器與參數(shù)合起來(lái)成為“消息”。
編譯器在看到此消息后,將其轉(zhuǎn)換為一條標(biāo)準(zhǔn)的C語(yǔ)言函數(shù)調(diào)用objc_msgSend,其原型如下:
void objc_msgSend(id self, SEL cmd, ...)
?解釋:這是個(gè)參數(shù)可變的函數(shù)。第一個(gè)參數(shù)代表接收者,第二個(gè)參數(shù)代表選擇器,后續(xù)參數(shù)就是消息中的那些參數(shù),其順序不變。
對(duì)先前例子中的消息進(jìn)行轉(zhuǎn)換,如下:
id returnValue = objc_msgSend(someObject, @selector(messageName:), parameter);
解釋:objc_msgSend函數(shù)會(huì)依據(jù)接收者與選擇器的類型來(lái)調(diào)用適當(dāng)?shù)姆椒?。為了完成此操?#xff0c;該方法需要在接收者所屬的類中搜尋其“方法列表”,如果能找到與選擇器名稱相符的方法,就跳至其實(shí)現(xiàn)代碼。若是找不到,那就沿著繼承體系繼續(xù)向上查找,等找到合適的方法之后再跳轉(zhuǎn)。如果最終還是找不到相符的方法,那就執(zhí)行“消息轉(zhuǎn)發(fā)”(message forwarding)操作。
3. 消息派發(fā)的特殊情況
- objc_msgSend_stret:如果待發(fā)送的消息要返回結(jié)構(gòu)體,那么可交由此函數(shù)處理。
- objc_msgSend_fpret:如果消息返回的是浮點(diǎn)數(shù),那么交由此函數(shù)處理。
- objc_msgSendSuper:如果要給超類發(fā)消息,例如[super message:parameter],那么就交由此函數(shù)處理。
4. 尾調(diào)用優(yōu)化
objc_msgSend等函數(shù)一旦找到應(yīng)該調(diào)用的方法實(shí)現(xiàn)之后,就會(huì)“跳轉(zhuǎn)過去”。之所以能這么做,是因?yàn)镺bjective-C對(duì)象的每個(gè)方法都可以視為簡(jiǎn)單的C函數(shù),其原型如下;
<return_type> Class_selector(id self, SEL _cmd, ...)
?
解釋:每個(gè)類里都有一張表格,其中的指針都會(huì)指向這種函數(shù),而選擇器的名稱則是查表時(shí)所用的“鍵”。objc_msgSend等函數(shù)正是通過這張表格來(lái)尋找應(yīng)該執(zhí)行的方法并跳至其實(shí)現(xiàn)的。其中,所使用的“尾調(diào)用優(yōu)化”(tail-call optimization)技術(shù),可以讓“跳至方法實(shí)現(xiàn)”這一操作變得更簡(jiǎn)單些。但是,只有當(dāng)某函數(shù)的最后一個(gè)操作僅僅是調(diào)用其他函數(shù)而不會(huì)將其返回值另作他用時(shí),才能執(zhí)行“尾調(diào)用優(yōu)化”。
要點(diǎn)
- 消息由接收者、選擇器及參數(shù)構(gòu)成。給某對(duì)象“發(fā)送消息”(invoke a message)也就相當(dāng)于在該對(duì)象上“調(diào)用方法”(call a method)。
- 發(fā)給某對(duì)象的全部信息都要由“動(dòng)態(tài)消息派發(fā)系統(tǒng)”(dynamic message dispatch system)來(lái)處理,該系統(tǒng)會(huì)查出對(duì)應(yīng)的方法,并執(zhí)行其代碼。