runtime的消息交換

Method Swizzing

顧名思義,就是講2個方法進行交換,由原來的  A---MethodA_A  B---Method_B,變?yōu)?A---Method_B  B---Method_A

Method Swizzing有什么用處呢?

比如說我們想統(tǒng)計每一個ViewController展示給用戶的次數(shù),我們可以在每個ViewController里的ViewDidApper里添加跟蹤代碼,但是這個過于麻煩,需要在每個ViewController里寫重復的代碼。
  • 我們可以創(chuàng)建一個子類,但是需要創(chuàng)建UIViewController、UITableViewController、UINavigationController以及UIKit里的ViewController的子類,同樣會很麻煩
  • 在這種情況下我們就可以使用Method Swizzing

Method Swizzing相關函數(shù)介紹

1、獲取一個方法的SEL

class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name)
  • 參數(shù)一:方法所在類
  • 參數(shù)二:方法名

2、獲取一個方法的IMP

class_getMethodImplementation(Class _Nullable cls, SEL _Nonnull name) 

3、添加一個方法

class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, const char * _Nullable types) 
  • 參數(shù)一:添加方法所在類
  • 參數(shù)二:添加方法名
  • 參數(shù)三:指向一個方法實現(xiàn)的指針
  • 參數(shù)四:參數(shù)類型的說明(方法返回值,參數(shù)等信息)

4、用一個方法替換另外一個方法

class_replaceMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, const char * _Nullable types)

5、交換方法

method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2)

Method Swizzling 注意要點

一、在+load()方法中實現(xiàn)

Objective-C在運行時會自動調(diào)用類的兩個方法+load和+initialize。+load會在類初始加載時調(diào)用, +initialize方法是以懶加載的方式被調(diào)用的,如果程序一直沒有給某個類或它的子類發(fā)送消息,那么這個類的 +initialize方法是永遠不會被調(diào)用的。所以Swizzling要是寫在+initialize方法中,是有可能永遠都不被執(zhí)行。

二、使用dispatch_once 中執(zhí)行

    Swizzling會改變?nèi)譅顟B(tài),所以在運行時采取一些預防措施,使用dispatch_once就能夠確保代碼不管有多少線程都只被執(zhí)行一次。如果不寫進行了偶數(shù)次的交換,就相當于沒有交換。

參考文章:runtime 黑魔法 Method Swizzing http://zhangzr.cn/2018/02/06/iOS%E5%BC%80%E5%8F%91-runtime-%E9%BB%91%E9%AD%94%E6%B3%95Method-swizzling/

runtime 如何使用https://halfrost.com/how_to_use_runtime/

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容