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大階段:

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ā)。

