iOS 為何使用runtime方法交換多次后卻能按照交換順序依次執行代碼邏輯?


題目: 假設我們有一個ViewController, 

Category A(ViewController),

Category B(ViewController),

Category C(ViewController)

4個文件, 其中3個category中都實現了自定義viewDidLoad方法, 會對ViewController中的ViewDidLoad方法進行方法替換, 那么依次替換后(A B C)的方法執行順序是什么呢?

記method_exchangeImplementations(Method _Nonnullm1, Method _Nonnullm2) 方法多次執行的代碼執行邏輯.

假設我們的方法替換由我們指定的一個category D來完成3次交換過程,代碼如下圖

那么接下來我們就詳細來探究一下每次追加一個方法交換,會對原方法有什么改變。

1. IMP方法實現交換

第一趟: 交換 原方法 和 A 

ViewController的原方法如下 

在category A中方法如下: 

交換后類實例方法和IMP的指向如下: 

方法調用: 

交換后, 調用class 0(ViewController)的selector0, 會調用category A的IMP1, 既打印 “extension A viewDidLoad”, 然后調用了category A的Sel, 就會去執行 class 0(ViewController)的IMP, 既打印 “origin viewDidLoad method”;

控制台打印如下: 

 接下來追加方法交換: 在原有方法交換基礎上 追加 交換原方法 和 B 

在category B中方法如下:  

交換后類實例方法和IMP的指向如下: 

代碼執行: 執行Sel0—>IMP2—>SelB—>IMP1—>SelA—>IMP, 所以控制台輸入順序為 B A 0

控制台輸出如下:

 繼續追加方法交換: 在原有方法交換基礎上 追加 交換原方法 和 C 

在category C中方法如下:  

交換后類實例方法和IMP的指向如下: 

代碼執行: 先執行Sel0-->IMP3—>SelC—>IMP2—>SelB—>IMP1—>SelA—>IMP, 所以控制台輸入順序為 C B A 0

控制台輸出如下: 

由此可以推理出來: 

我們依次追加n個對原方法交換, 那么class 0對應的Sel0執行的IMP會偏移指向最后一個方法交換的Sel, 那么就會按照交換前后順序執行邏輯.

Demo地址: https://github.com/Winerywine/MethodExchange.git

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM