題目: 假設我們有一個ViewController, Category A(ViewController), Category B(ViewController), Category C(ViewController) 4個文件, 其中3個category中都實現了自定義viewDidLoad方法, ...
題目: 假設我們有一個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