【iOS】消息轉(zhuǎn)發(fā)機(jī)制

在編譯期向某類發(fā)送了其無(wú)法理解的消息并不會(huì)報(bào)錯(cuò),因?yàn)樵谶\(yùn)行期可以繼續(xù)向類中添加方法,所以編譯器在編譯時(shí)還不確定類中到底有沒(méi)有某個(gè)方法的實(shí)現(xiàn)。當(dāng)對(duì)象接收到無(wú)法解讀的消息后,就會(huì)啟動(dòng)消息轉(zhuǎn)發(fā)機(jī)制。
消息轉(zhuǎn)發(fā)分為兩大階段。第一階段先征詢接受者。所屬的類,看其是否能動(dòng)態(tài)添加方法以處理這個(gè)未知的selector,叫做動(dòng)態(tài)方法解析。第二階段“完整的消息轉(zhuǎn)發(fā)機(jī)制”。

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

對(duì)象收到無(wú)法解讀的消息后,首先將調(diào)用其所屬類的下列類方法:
+(BOOL)resolveInstanceMethod:(SEL)selector
假如尚未實(shí)現(xiàn)的方法不是實(shí)例方法而是類方法,則會(huì)調(diào)用本類的方法:
+(BOOL)resolveClassMethod(SEL)selector
該方法參數(shù)就是那個(gè)未知的selector,其返回值類型為BOOL類型,表示這個(gè)類是否能新增一個(gè)方法用以處理此selector。

備援接受者

當(dāng)前接受者還有第二次機(jī)會(huì)處理未知selector,在這一步中,運(yùn)行系統(tǒng)會(huì)問(wèn)它能否把此消息交給其他接受者處理。對(duì)應(yīng)的處理方法如下:
- (id)forwardingTargetForSelector:(SEL)selector
若當(dāng)前接受者能找到備援對(duì)象,則將其返回,若找不到則返回nil。在一個(gè)對(duì)象內(nèi)部,可能還有一系列其他對(duì)象,該對(duì)象可經(jīng)由此方法將能夠處理某選擇子的相關(guān)內(nèi)部對(duì)象返回,這樣,外界看來(lái)好像是該對(duì)象親自處理這些消息。

完整的消息轉(zhuǎn)發(fā)

這是消息轉(zhuǎn)發(fā)流程的最后一個(gè)環(huán)節(jié)。首先創(chuàng)建NSInvocation對(duì)象,把尚未處理的那條消息有關(guān)的全部細(xì)節(jié)都封于其中。此對(duì)象包括選擇子,目標(biāo),及參數(shù)。再出發(fā)NSInvocation對(duì)象時(shí),消息派發(fā)系統(tǒng)將親自出馬把消息指派給目標(biāo)對(duì)象
此步驟會(huì)調(diào)用一下方法來(lái)轉(zhuǎn)發(fā)消息:
-(void)forwardInvocation:(NSInvocation*)invocation

0CE8229C-6F22-417B-BDFB-57F119F03AA9.png

如果經(jīng)過(guò)上面三個(gè)步驟都沒(méi)有處理這個(gè)消息,就會(huì)進(jìn)入NSObjecte 的 - (void)doesNotRecognizeSelector:(SEL)aSelector方法中,拋出異常。

接受者在每一步都有機(jī)會(huì)處理消息,步驟越往后處理消息的代價(jià)就越大。最好在第一部就處理了完成,正陽(yáng)的話,運(yùn)行期系統(tǒng)就可以將此方法緩存起來(lái)。

最后編輯于
?著作權(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ù)。

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

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