objc_msgSend
在 OC中,如果向某對(duì)象傳遞消息,那就會(huì)使用動(dòng)態(tài)綁定機(jī)制來(lái)決定需調(diào)用的方法
在底層,所以的方法都是 c函數(shù)。對(duì)象接受到消息之后,調(diào)用哪一個(gè)方法,在運(yùn)行期決定,甚至可以在程序運(yùn)行時(shí)決定
給對(duì)象發(fā)送消息的代碼
//在 oc 中發(fā)送消息就可以寫(xiě)成這樣
id returnValue = [someObject messageName:parameter];
//編譯器看到上面的代碼,就會(huì)轉(zhuǎn)換為 c 語(yǔ)言函數(shù)
void objc_msgSend(id self,SEL cmd,...)
//可變參數(shù),意思就是想 self這個(gè)對(duì)象發(fā)送消息
//接受者-》someObject 選擇子(方法)-》messageName: 要這個(gè)接受者調(diào)用這個(gè)選擇子
id returnValue = objc_msgSend(someObject,@seletor(messageName:),parameter)
原理
objc_msgSend函數(shù)會(huì)依據(jù)接收者與選擇子的類(lèi)型來(lái)調(diào)用適當(dāng)?shù)姆椒?/p>
- 這個(gè)函數(shù)會(huì)在接收者的類(lèi)中搜尋其 方法列表.如果找到了就跳轉(zhuǎn)到其實(shí)現(xiàn)代碼。
- 如果沒(méi)有找到,就沿著繼承體系繼續(xù)向上查找,等找到合照的方法再跳轉(zhuǎn)
- 最后還是沒(méi)有找到的話,就執(zhí)行 消息轉(zhuǎn)發(fā)
特殊情況
-
objc_msgSend_stret如果發(fā)送的消息返回的是結(jié)構(gòu)體,就用這個(gè)函數(shù)處理。如果期存器能夠存下這個(gè)結(jié)構(gòu)體,就處理。不能的話,就消息派發(fā)。由分配在棧上的某個(gè)變量來(lái)處理消息返回的結(jié)構(gòu)體 -
objc_msgSend_fpret如果消息返回的是浮點(diǎn)數(shù),就由這個(gè)函數(shù)處理 -
objc_msgSendSuper如果要給超類(lèi)發(fā)送消息。例如[super message:parameter] 就由這個(gè)函數(shù)處理 另外還有兩個(gè)與上面的等效的函數(shù)。來(lái)處理super 的消息