在理解這一套東西之前,我們先理清楚幾個函數(shù)的意義
1.?class_addMethod(aClass, originalSel, method_getImplementation(swizzleMethod), method_getTypeEncoding(swizzleMethod))
????????這個函數(shù)的意義是丘薛,給一個類aClass,添加一個SEL originalSel切油, 如果該類已經(jīng)實現(xiàn)了originalSel,則添加失敗,返回NO
????????哪怕aClass 的父類實現(xiàn)了originalSel,也會返回NO
? ??????swizzleMethod必須是實現(xiàn)了的IMP,否則會crash
? ? ? ? 常見用法:
? ? ? ?1. 給類未實現(xiàn)的SEL钞馁,改變IMP
? ? ? ? 2. 檢查本類是否實現(xiàn)了某個方法(使用method_exchangeImplementations時,添加該檢測匿刮,避免影響父類)
? ? ? ? 我們來看一個簡單的例子僧凰,自己踩過的坑,覺得很low 的請自行略過熟丸,大致代碼邏輯如下
? ? ? ? ClassA : NSObejct -> 有一個func works()
? ? ? ? ClassB : NSObject -> 有一個func bWorks()
? ? ? ? 在 ClassB的load 中训措,添加method_exchangeImplementations(work,bwork)
? ? ? ? 按照我以前的想法,ClassB中 交換了work 和bWork, 這對A不會有什么影響光羞,所以绩鸣,A在調(diào)用work()時,應(yīng)該是work()的實現(xiàn)
? ? ? ? 然而纱兑, 結(jié)果是a 調(diào)用work()時呀闻,內(nèi)容是bWork()的實現(xiàn),why?
? ? ? ? 這是因為
ClassA do load -> ClassB do load -> exchange works() bWorks()實現(xiàn) ->
b 中找不到works() 的SEL潜慎, 往父親找总珠,找到了 -> 交換父親的works() SEL 與 bWorks() 的SEL
? ? ? 這顯然不是我們想要的結(jié)果,一般情況下我們的目的只是影響本類或者子類勘纯,而不想影響父類局服,那么怎么辦呢
2.?class_replaceMethod(aClass, swizzleSel, originalMethodIMP, originalMethodEncodeing)
? ? ? ? 用一個SEL 替換另外一個IMP實現(xiàn)
????????aClass ? : 將要操作的類
? ??????swizzleSel : 用于替換的SEL
? ? ? ??originalMethodIMP : 被替換的IMP
????????originalMethodEncodeing? ?: 被替換的IMPEncodeing
3. method_exchangeImplementations(originalMethod, swizzleMethod)?
????????交換兩個method
? ? ? ? 我們接著說第一個方法中的case,怎么辦呢驳遵,我們可以這樣
? ??????
? ? 子類中淫奔,發(fā)現(xiàn)本類沒有實現(xiàn)的method(可能父類實現(xiàn)了),直接替換methodIMP
? ? 如果是本類實現(xiàn)的method堤结,再交換method
case1 : 子類沒有實現(xiàn)父類的方法
ClassA do load -> ClassB do load -> Classb 中唆迁,bWorks() 替換了works() 方法?
-> a call works() -> a 就調(diào)用a 的works()
case2 : 子類實現(xiàn)了父類的方法
ClassA do load -> ClassB do load -> exchange 類B中 works() bWorks() IMP
-> a call works() -> a 的works() 的IMP 沒有改變,所以還是ClassA中works() 的實現(xiàn)
Swizzle 用途:
1. 頁面統(tǒng)計竞穷,比如ViewController 中唐责,添加category, 在category 中使用Swizzle瘾带, 統(tǒng)計頁面
2. 對系統(tǒng)類的一些方法鼠哥,提供改善,比如 NSArray,NSMutableArray朴恳,NSDictionary抄罕,NSMutableDictionary
,Xcode 10 以前于颖,數(shù)組越界呆贿,插入nil 會crash,可以對對應(yīng)的方法加hook森渐,使不crash做入,Xcode 10 以后盡管不會crash了,但是還是可以對系統(tǒng)的方法進行我們需要的改善
? ? ? ??