1.當(dāng)對象接收到無法解讀的消息之后,就會啟動消息轉(zhuǎn)發(fā)機(jī)制,程序員可經(jīng)由此告訴對象應(yīng)該如何處理位置消息。
2.消息轉(zhuǎn)發(fā)分為兩大階段。第一階段先征詢接受者。所屬的類,看其能否動態(tài)添加方法,已處理當(dāng)前這個位置的選擇子,這個叫做動態(tài)方法解析。第二階段涉及完整的消息轉(zhuǎn)發(fā)機(jī)制,如果運行期系統(tǒng)已經(jīng)把第一階段執(zhí)行完了,那么接受者自己就無法在以動態(tài)新增方法的手段來響應(yīng)包含選擇子的消息了,接下來就會以其他手段來處理與消息相關(guān)的方法調(diào)用,
分為兩步:a.請接受者看看有沒有其他對象能處理這條消息。有的話就把消息給他。b.如果沒有備源接收者則啟動完整的消息轉(zhuǎn)發(fā)機(jī)制,運行期系統(tǒng)會把與消息有關(guān)的全部細(xì)節(jié)都封裝到NSInvocation對象中。再給接收者最后一次機(jī)會。
3.resolveInstanceMethod:(SEl)selector 返回值表示這個類能否新增一個實例方法泳衣處理此選擇子,在繼續(xù)往下執(zhí)行轉(zhuǎn)發(fā)機(jī)制之前,本類有機(jī)會新增一個處理此選擇子的方法。如果添加的是類方法。叫做resolveClassMethod。
4.如果類不能動態(tài)解析選擇子,則會啟動備援接收者,-(id)forwardingTargetForSelector:(SEL)selector,方法參數(shù)代表位置的選擇子,若當(dāng)前接受者能找到備援對象,則將其返回,若找不到就返回nil。
5.完整的消息轉(zhuǎn)發(fā)
如果轉(zhuǎn)發(fā)算法已經(jīng)來到這一步的話,那么唯一能做的就是啟動完整的消息轉(zhuǎn)發(fā)機(jī)制了,首先創(chuàng)建NSInvocation對象,把尚未處理的那條消息有關(guān)的全部細(xì)節(jié)都封裝于其中。此對象包含選擇子,目標(biāo)及參數(shù)。在出發(fā)NSInvocation對象時,消息派發(fā)系統(tǒng)將親自出馬,把消息指派給目標(biāo)對象。
-(void)forwardInvocation:(NSInvocation *)invocation
6.接收者在每一步中均有機(jī)會處理消息,步驟越往后。處理消息的代價就越大。最好能在第一步就處理完,這樣的話,運行期系統(tǒng)就可以將此方法緩存起來了,如果這個類的實例稍后還收到同名選擇子,那么根本就無需啟動消息轉(zhuǎn)發(fā)流程。