消息轉(zhuǎn)發(fā)三部曲
接下來的內(nèi)容都和消息轉(zhuǎn)發(fā)有關(guān), 所以有必要先簡單介紹一下OC的消息轉(zhuǎn)發(fā)機制:
+ (BOOL)resolveInstanceMethod:(SEL)sel
當(dāng)向?qū)ο蟀l(fā)送消息而對象沒有對應(yīng)的實現(xiàn)時, 消息會通過+(BOOL)resolveInstanceMethod:方法詢問具體的接收類: 沒有實現(xiàn)的話, 你能不能現(xiàn)在造一個實現(xiàn)出來?
通乘┦拢現(xiàn)場造出消息實現(xiàn)都是走的class_addMethod添加對應(yīng)的實現(xiàn), 然后回答YES, 那么此次消息發(fā)送算是成功的, 否則進入下一步.
- (id)forwardingTargetForSelector:(SEL)aSelector
上一步?jīng)]有結(jié)果的話消息會進行二次詢問: 造不出來沒關(guān)系, 你告訴我誰有這個消息的對應(yīng)實現(xiàn)? 我去它那找也行的.
此時如果返回一個能響應(yīng)該消息的對象, 那么消息會轉(zhuǎn)發(fā)到返回對象那里, 如果返回nil或者返回對象不能相應(yīng)此消息, 進行最后一步.
- (void)forwardInvocation:(NSInvocation *)anInvocation
到了這一步, 消息發(fā)送其實算是失敗了, 不會再有詢問過程, 而是直接將消息攜帶的一切信息包裹在NSInvocation中交給對象自己處理. 另外, forwardInvocation:在構(gòu)造Invocation時會調(diào)用methodSignatureForSelector:獲取方法簽名, 所以一般情況下還需要實現(xiàn)這個方法返回相應(yīng)的方法簽名.
此時如果對象拿到invocation中的信息有能力發(fā)起[Invacation invoke], 那么消息對應(yīng)的實現(xiàn)還是能正常進行, 只是相對于正常的發(fā)送過程稍微麻煩耗時些, 否則就會觸發(fā)消息不識別的異常返回.