iOS 消息機(jī)制

OC的消息機(jī)制,會(huì)經(jīng)常在面試中被問(wèn)到,所以這里記錄一下,

消息發(fā)送

首先會(huì)判斷receiver 是否為nil,假如為nil,那么就什么也不做,假如不為nil,那么就會(huì)去receiverClass的方法緩存里面查找方法,假如找到了就會(huì)調(diào)用方法,假如找不到,就會(huì)去receiverClass的方法列表中查找方法,假如也找不到,就去superClass的方法緩存中查找,也沒(méi)找到,就會(huì)去superClass的方法列表里面找,直到一直找到了基類也沒(méi)有找到,那么它就會(huì)開始動(dòng)態(tài)方法解析,假如中間哪一步找到了方法,那么就會(huì)調(diào)用方法,結(jié)束查找,并把方法緩存到receiverClass的方法緩存中去


未命名文件2.png
動(dòng)態(tài)解析

首先會(huì)判斷是否動(dòng)態(tài)解析過(guò),假如已經(jīng)動(dòng)態(tài)解析過(guò)了,那么就會(huì)進(jìn)入消息轉(zhuǎn)發(fā)階段,假如沒(méi)有,那么就會(huì)調(diào)用+resolveInstanceMethod:或者 +resolveClassMethod:方法,開發(fā)者可以實(shí)現(xiàn)這兩個(gè)方法來(lái)達(dá)到動(dòng)態(tài)添加方法實(shí)現(xiàn)的目的,調(diào)用完方法之后,會(huì)標(biāo)記為已經(jīng)動(dòng)態(tài)解析過(guò)了,并會(huì)重新走“消息發(fā)送”流程,從receiverClass的緩存中查找方法這一步開始執(zhí)行。


未命名文件3.jpg
消息轉(zhuǎn)發(fā)

首先會(huì)調(diào)用forwardingTargetForSelector:方法,假如不為nil, 那么就會(huì)拿到返回值,調(diào)用objc_msgSend(返回值,SEL),假如返回值為nil,那么就會(huì)調(diào)用methodSignatureForSelector:,假如methodSignatureForSelector:返回值不為nil,就會(huì)調(diào)用forwardInvocation:方法,開發(fā)者可以在這個(gè)方法中自定義任何邏輯,假如返回值為nil,那就會(huì)調(diào)用doesNotRecognizeSelector:方法,
forwardingTargetForSelector:與methodSignatureForSelector:有對(duì)象方法和類方法兩個(gè)版本,可根據(jù)開發(fā)需要,自行選擇。


未命名文件4.jpg
最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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