基礎條件
使用runtime的特性,進行方法交換
原理:
在iOS中,使用函數,可以把函數分為兩個部分,即方法名與方法體(selector and method),一個方法名對應其方法體
eg:print(){
log ("A")
}
print即為方法名,大括號里面的即為方法體。
當我們進行方法交換的時候,首先通過runtime的特性獲取其方法名。然后根據其方法名獲取其方法體,最后實現交換的方法
例如A類中有兩個方法printA與printB。
//獲取printA和printB的Selector
? ? ? ? let printASelector = #selector(A.printA)
? ? ? ? let printBSelector = #selector(A.printB)
? ? ? ? //獲取printA和printB的Method
? ? ? ? let printAMethod = class_getInstanceMethod(self, printASelector)
? ? ? ? let printBMethod = class_getInstanceMethod(self, printBSelector)
?? ? ? ?//交換兩個方法的Method
? ? ? ? method_exchangeImplementations(printAMethod, printBMethod)
這樣就是黑魔法發的本質,其實還是跟語言特性有關,Objective-C的消息機制,雖然Swift已經完全不同Objective-C,但是為了兼容,只要該類繼承與NSObject,依然保留其消息機制的特性,需要注意的是在Swift中使用的時候,需要在加入@objc,dynamic關鍵字。