OC消息轉(zhuǎn)發(fā)機(jī)制

消息轉(zhuǎn)發(fā)的兩大階段

  1. 先征詢接收者,所屬的類,看其是否能夠動(dòng)態(tài)添加方法,以處理這個(gè)『未知的選擇子』,這叫做動(dòng)態(tài)方法解析

  2. 第一階段執(zhí)行完了,那么接收者自己就無(wú)法再以動(dòng)態(tài)新增方法的手段來(lái)處響應(yīng)包含改選擇子的消息了。此時(shí),運(yùn)行期系統(tǒng)會(huì)請(qǐng)求接收者以其他手段來(lái)處理與消息相關(guān)的方法調(diào)用。又分為亮度

    2.1 接收者看有沒(méi)有其他的對(duì)象能夠處理這條消息。如果有,就把消息轉(zhuǎn)發(fā)給這個(gè)對(duì)象處理,然后消息轉(zhuǎn)發(fā)過(guò)程結(jié)束。

    2.2 若沒(méi)有「?jìng)湓慕邮照摺?,則啟動(dòng)完整的消息轉(zhuǎn)發(fā)機(jī)制運(yùn)行期系統(tǒng)會(huì)把與消息有關(guān)的全部細(xì)節(jié)封裝到 NSInvocation 對(duì)象中,在給接收者最后一次機(jī)會(huì),令其設(shè)法解決當(dāng)前還未處理的這條消息

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

  1. 對(duì)象在收到無(wú)法解讀的消息之后,首先會(huì)調(diào)用所屬類的下列類方法:
+ (BOOL) resolveInstanceMethod:(SEL) selector;
//參數(shù)是那個(gè)未知的選擇子,其返回值是 BOOL 表示這個(gè)類是否能夠新增一個(gè)實(shí)例方法用以處理這個(gè)消息
//在繼續(xù)往下執(zhí)行轉(zhuǎn)發(fā)機(jī)制之前,本類有機(jī)會(huì)新增一個(gè)處理此選擇子的方法
//加入尚未實(shí)現(xiàn)的方法不是實(shí)例方法而是類方法,那么運(yùn)行期系統(tǒng)就會(huì)調(diào)用 resoleClassMethod:

//使用這種方法的前提:相關(guān)的實(shí)現(xiàn)代碼已經(jīng)寫好了,只等運(yùn)行的時(shí)候動(dòng)態(tài)插在類中就行了

備援接收者

當(dāng)前接收者還有第二次機(jī)會(huì)處理未知的選擇子。運(yùn)行期系統(tǒng)會(huì)問(wèn)他:能不能把這條消息交給其他的接收者來(lái)處理 對(duì)應(yīng)的方法:

//方法參數(shù)代表未知的選擇子,若當(dāng)前接收者能找到備援對(duì)象,則將其返回。若找不到,就返回nil
- (id) forwardingTargetForSelector:(SEL) selector;

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

  • 創(chuàng)建 NSInvocation 對(duì)象,把與尚未處理的那條消息有關(guān)的全部細(xì)節(jié)封裝在這里面。包括 選擇子、目標(biāo)、參數(shù)。
  • 在觸發(fā) NSInvocation 對(duì)象,「消息派發(fā)系統(tǒng)」將親自出馬,把消息指派給目標(biāo)對(duì)象
//調(diào)用這個(gè)方法
- (void) forwardInvocation:(NSInvocation *) invocation;
  • 這個(gè)方法實(shí)現(xiàn)起來(lái)很簡(jiǎn)單:只需改變調(diào)用目標(biāo) 和 備援接收者 類型
  • 還有一種實(shí)現(xiàn)方式:在觸發(fā)消息前,先以某種方式改變消息內(nèi)容,比如追加另外一個(gè)參數(shù),或者是改變選擇子,等等

消息轉(zhuǎn)發(fā)全流程

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