當前位置:編程學習大全網 - 編程語言 - —— iOS 運行時中方法的調用流程

—— iOS 運行時中方法的調用流程

在iOS運行時系統中,調用方法的本質就是利用objc_msgSend進行消息發送:

iOS 中所有的類都是繼承於 NSObject,壹個對象所具有的方法分為實例方法和類方法,編譯完成後的對象中,存在壹個實例方法鏈表、壹個緩存方法鏈表。當實例調用方法經objc_msgSend時:首先,在相應操做的對象中的緩存方法列表中找調用的方法,若找到,轉向相應的實現並執行;若沒找到,在對象的方法列表中查找,若是找到,轉向相應的實現並執行;若是沒找到,則遞歸的去父類指針所指向的類對象方法列表中查找;以此類推,若是壹直到根類都沒有找到,轉向攔截調用,走消息轉發機制;若是沒有重寫攔截調用方法,程序報錯;

消息轉發也被稱為攔截調用,就是在找不到調用的方法後,且在程序崩潰以前,有機會經過重寫NSObject的四個方法來補救處理:

若以上都不中,調用 NSObject 的 doesNotRecognizeSelector 方法拋出異常:

利用以上機制,可以對resolveInstanceMethod 和 resolveClassMethod 兩個方法進行方法交換,攔截可能出現的 iOS 崩潰,然後自定義處理。

消息轉發機制依次的三個過程:1)動態方法解析;2)轉發給其他備用的接收對象;3)消息所有相關內容封裝成壹個NSInvocation對象,再做最後的嘗試。

第壹階段,先征詢接收者所屬的類,是否需要動態的添加方法,用來處理當前未找到的方法。對象在無法解讀消息時會首先調用所屬類的下列類方法,來判斷是否能接收消息:

例:

第二階段,如果動態方法解析沒有發現添加的方法,那麽嘗試轉發給其他對象來處理這個方法。該步驟調用的方法是:

例:

第三階段,如果沒有可用的備選者,那麽系統就會把消息所有相關內容封裝成壹個NSInvocation對象,再做最後的嘗試,啟動完整的消息轉發。先調用methodSignatureForSelector:獲取方法簽名,然後再調用forwardInvocation:進行處理,這壹步的處理可以直接轉發給其它對象,即和第二步的效果等效,但是很少有人這麽幹,因為消息處理越靠後,就表示處理消息的成本越大,性能的開銷就越大。所以,在這種方式下,壹般會改變消息內容,比如增加參數,改變選擇子等等,具體根據實際情況而定。

例:

這裏就是利用了消息轉發機制的第三個階段,將NSIvocation分發給多個代理去響應。

bang.net/tech/2808/

bang.net/tech/2855/

由於OC的動態特性,在編譯過程向類發送了其無法理解的消息並不會報錯,因為在運行時,我們可以改變對象調用的方法、向類中添加方法。只有當程序運行起來之後,才知道要真正執行哪個函數(動態綁定)。

OC消息發送原理、方法查找過程:

簡單理解:

OC、運行時初始化時機:

blogs.com/feng9exe/p/10397102.html

/a/02d9b8b219b24d888ef93b97.html

/p/e24b3420f1b4

  • 上一篇:c語言萬年歷代碼
  • 下一篇:傳祺M8商用車也可以這樣升級。
  • copyright 2024編程學習大全網