方法調(diào)用底層實(shí)現(xiàn)

runtime怎么實(shí)現(xiàn)方法的調(diào)用 :消息機(jī)制,runtime系統(tǒng)會(huì)把方法調(diào)用轉(zhuǎn)化為消息發(fā)送。即objc-msgSend。并把方法的調(diào)用者和方法選擇器當(dāng)做參數(shù)傳遞過(guò)去,這也是我們?yōu)槭裁丛诜椒ㄖ锌梢允褂胹elf的原因。

objc_msgSend的執(zhí)行流程可以分為3大階段

objc_msgSend的執(zhí)行流程

1.首先檢測(cè)這個(gè)selector是不是要忽略像mac osx開(kāi)發(fā),有了垃圾回收就不會(huì)理會(huì)retain,release函數(shù)

2.檢測(cè)這個(gè)selector的target是不是nil.objc允許我們向一個(gè)nil對(duì)象執(zhí)行任何方法不會(huì)Crash,因?yàn)檫\(yùn)行時(shí)會(huì)查找該對(duì)象的isa指針,直接就0地址返回了.

3,如果上面兩步都通過(guò),就直接查找這個(gè)類(lèi)的實(shí)現(xiàn)IMP,為了效率,優(yōu)先在cache中查找,找到后就跳到對(duì)應(yīng)的方法中執(zhí)行。

4.如果cache找不到,就在類(lèi)的methodLists(實(shí)例方法))中查找,如果找到了就調(diào)用方法,結(jié)束查找,并將方法緩存到receiveClass的cache中

5.如果類(lèi)的方法列表中找不到就通過(guò)superclass指針往上一級(jí)超類(lèi)查找(類(lèi)方法存放在元類(lèi)中、Class通過(guò)isa指針即可找到其所屬的元類(lèi)),找到了,就結(jié)束查找并將方法緩存到receiveClass的cache中,沒(méi)找到一直找到NSObject類(lèi)為止

6.如果還是找不到,就會(huì)進(jìn)入動(dòng)態(tài)方法解析

在對(duì)象收到無(wú)法處理的消息之后,會(huì)執(zhí)行消息轉(zhuǎn)發(fā),消息轉(zhuǎn)發(fā)有三個(gè)步驟:

1調(diào)用 resolveInstanceMethod 方法。動(dòng)態(tài)方法解析,這里會(huì)給類(lèi)使class_addMethod 來(lái)增加方法的機(jī)會(huì)。

2調(diào)用 forwardingTargetForSelector 方法,看是否有備用接收者,將消息轉(zhuǎn)發(fā)給備用接收者處理。

3調(diào)用 methodSignatureForSelector 和 forwardInvocation 方法,進(jìn)行完成的消息轉(zhuǎn)發(fā)。

動(dòng)態(tài)方法解析


方法轉(zhuǎn)發(fā)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容