基础条件
使用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关键字。