iOS中的所有類都繼承自NSObject,壹個對象的方法可以分為實例方法和類方法。編譯後的對象中有壹個實例方法鏈表和壹個緩存方法鏈表。當壹個實例通過objc_msgSend調用壹個方法時:首先在對應的操作對象中的緩存方法列表中找到被調用的方法,如果找到,則轉向對應的實現並執行;如果沒有找到,就在對象的方法列表中查找;如果找到,轉到相應的實現並執行;如果沒有找到,遞歸到父類指針指向的對象方法列表中查找;以此類推,如果找不到根類,轉而攔截調用,采取消息轉發機制;如果不重寫攔截調用方法,程序報錯;
消息轉發,也稱攔截調用,是指在被調用的方法找不到之後,程序崩潰之前,有機會重寫NSObject的四個方法進行補救:
如果以上都不正確,請調用NSObject的doesNotRecognizeSelector方法並引發異常:
使用上述機制,我們可以在resolveInstanceMethod和resolveClassMethod之間交換方法,攔截可能的iOS崩潰,然後自定義處理。
消息轉發機制依次有三個流程:1)動態方法分析;2)轉發給其他備用接收對象;3)將消息的所有相關內容封裝到壹個NIS調用對象中,然後進行最後壹次嘗試。
第壹階段,先問接收者所屬的類,是否需要動態添加方法來處理目前沒有找到的方法。當對象無法解釋消息時,它將首先調用其類的以下類方法來確定它是否可以接收消息:
示例:
在第二階段,如果動態方法分析沒有找到添加的方法,那麽嘗試將其轉發給其他對象來處理該方法。該步驟中調用的方法是:
示例:
在第三階段,如果沒有可用的候選,那麽系統將把消息的所有相關內容封裝到壹個NSInvocation對象中,然後進行最後的嘗試,開始完整的消息轉發。調用methodSignatureForSelector:以獲取方法簽名,然後調用forwardInvocation:進行處理。這壹步處理可以直接轉發給其他對象,相當於第二步的效果,但是很少有人這麽做,因為消息處理的越晚,處理消息的代價就越大,性能開銷也就越大。所以用這種方式,壹般會改變消息內容,比如添加參數,改變選擇器等。,視實際情況而定。
示例:
這是消息轉發機制的第三階段,它將位置分配給多個代理來響應。
bang.net/tech/2808/
bang.net/tech/2855/
由於OC的動態特性,在編譯時向類發送它無法理解的消息並不是錯誤,因為在運行時,我們可以改變對象調用的方法,向類添加方法。只有程序運行時,妳才知道實際執行哪個函數(動態綁定)。
OC消息發送和搜索過程的原理和方法;
簡單理解:
OC,運行時初始化時間:
blogs.com/feng9exe/p/10397102.html
/a/02d 9 b 8 b 219 b 24d 888 ef 93 b 97 . html
/p/e24b3420f1b4