_objc_msgForward是一個函數指針(和 IMP 的類型一樣),是用于消息轉發的:當向一個對象發送一條消息,但它并沒有實現的時候,_objc_msgForward會嘗試做消息轉發。
結合《NSObject官方文檔》,排除掉 NSObject 做的事,剩下的就是_objc_msgForward消息轉發做的幾件事:
-
調用resolveInstanceMethod:方法 (或 resolveClassMethod:)。允許用戶在此時為該 Class 動態添加實現。如果有實現了,則調用并返回YES,那么重新開始objc_msgSend流程。這一次對象會響應這個選擇器,一般是因為它已經調用過class_addMethod。如果仍沒實現,繼續下面的動作。
-
調用forwardingTargetForSelector:方法,嘗試找到一個能響應該消息的對象。如果獲取到,則直接把消息轉發給它,返回非 nil 對象。否則返回 nil ,繼續下面的動作。注意,這里不要返回 self ,否則會形成死循環。
-
調用methodSignatureForSelector:方法,嘗試獲得一個方法簽名。如果獲取不到,則直接調用doesNotRecognizeSelector拋出異常。如果能獲取,則返回非nil:創建一個 NSlnvocation 并傳給forwardInvocation:。
-
調用forwardInvocation:方法,將第3步獲取到的方法簽名包裝成 Invocation 傳入,如何處理就在這里面了,并返回非ni。
-
調用doesNotRecognizeSelector: ,默認的實現是拋出異常。如果第3步沒能獲得一個方法簽名,執行該步驟。
上面前4個方法均是模板方法,開發者可以override,由 runtime 來調用。最常見的實現消息轉發:就是重寫方法3和4,吞掉一個消息或者代理給其他對象都是沒問題的
也就是說_objc_msgForward在進行消息轉發的過程中會涉及以下這幾個方法:
-
resolveInstanceMethod:方法 (或 resolveClassMethod:)。
-
forwardingTargetForSelector:方法
-
methodSignatureForSelector:方法
-
forwardInvocation:方法
-
doesNotRecognizeSelector: 方法