Swift4.0中Runtime method_exchangeImplementations的使用和initialize()方法的替代
程序员文章站
2022-05-31 17:17:19
...
在swift4.0中
load()方法已经失效
initialize()也失效
一时间我一度不知道怎么用运行时的method_exchangeImplementations方法,后来在网上查看总结出来下面将代码贴出来
extension UIViewController {
public class func initializeMethod(){
let originalSelector = #selector(UIViewController.viewDidAppear(_:))
let swizzledSelector = #selector(UIViewController.myMethod(animated:))
let originalMethod = class_getInstanceMethod(self, originalSelector)
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
//在进行 Swizzling 的时候,需要用 class_addMethod 先进行判断一下原有类中是否有要替换方法的实现
let didAddMethod: Bool = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod!), method_getTypeEncoding(swizzledMethod!))
//如果 class_addMethod 返回 yes,说明当前类中没有要替换方法的实现,所以需要在父类中查找,这时候就用到 method_getImplemetation 去获取 class_getInstanceMethod 里面的方法实现,然后再进行 class_replaceMethod 来实现 Swizzing
if didAddMethod {
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod!), method_getTypeEncoding(originalMethod!))
} else {
method_exchangeImplementations(originalMethod!, swizzledMethod!)
}
}
@objc func myMethod(animated: Bool) {
self.myMethod(animated: animated)
print("替换了")
}
}
在AppDelegate的func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
方法中添加如下代码
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UIViewController.initializeMethod()
return true
}
下面看一下调用和打印结果