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/