對Objective-C 等面向?qū)ο笳Z言來說瞳遍,『對象』(object)就是『基本構(gòu)造單元』闻妓,開發(fā)者可以通過對象來存儲并傳遞數(shù)據(jù)。在對象之間傳遞數(shù)據(jù)并執(zhí)行任務(wù)的過程就叫做『消息傳遞』傅蹂。
Objective-C 是C 的超集纷闺,我們先來理解C語言的函數(shù)調(diào)用方式算凿。
C語言使用『靜態(tài)綁定』(static binding)。編譯器在編譯代碼的時候就已經(jīng)知道程序中的函數(shù)犁功,會直接生成調(diào)用相關(guān)函數(shù)的指令氓轰。
不同于C,在Objective-C中浸卦,如果向某對象傳遞消息署鸡,會使用『動態(tài)綁定』(dynamic binding)機(jī)制來決定需要調(diào)用的方法。在底層限嫌,所有方法都是普通的C語言函數(shù)靴庆,然而對象收到消息之后,究竟該調(diào)用哪個方法則完全取決于運(yùn)行期決定怒医,甚至可以在程序運(yùn)行時改變
給對象發(fā)送一條消息
id returenValue = [someObject messageName:parameter];
在本例中炉抒,someObject是消息的『接收者』(receiver),messageName是『選擇器』(selector)即方法名稚叹。
編譯器看到這條消息后焰薄,將其轉(zhuǎn)換為一條標(biāo)準(zhǔn)的C語言函數(shù)使用,所調(diào)用的函數(shù)是消息傳遞機(jī)制中的核心函數(shù)扒袖,叫做objc_msgSend,原形如下:
void objc_msgSend(id self, SEL cmd, ...);
這個是『參數(shù)個數(shù)可變的函數(shù)』塞茅,能接受兩個或者兩個以上的參數(shù)。第一個參數(shù)代表接收者季率,第二個參數(shù)代表選擇器野瘦,后續(xù)參數(shù)是消息中的那些參數(shù),其順序不變飒泻。
id returnValue = objc_msgSend(someObject , @selector(message:) , parameter);
objc_msgSend函數(shù)會依據(jù)接收者與選擇器的類型來調(diào)用適當(dāng)?shù)姆椒ū薰狻T摲椒ㄐ枰诮邮照咚鶎俚念愔兴褜て洹悍椒斜怼唬绻苷业脚c選擇器名稱相符的方法蠢络,就跳至其實現(xiàn)代碼衰猛。若是找不到,那就沿著繼承體系繼續(xù)向上查找刹孔,等找到合適的方法之后再跳轉(zhuǎn)。如果最終還是找不到相符的方法娜睛,就執(zhí)行『消息轉(zhuǎn)發(fā)』(message forwarding)髓霞。(后續(xù)介紹)
這一套就是『動態(tài)消息派發(fā)系統(tǒng)』(dynamic message dispatch system)。發(fā)送給對象的全部消息都由其處理畦戒,該系統(tǒng)會查出對應(yīng)的方法方库,并執(zhí)行其代碼。