- 想办法在程序启动的时候执行一次方法交换
- 方法1需要每个类都添加一个方法 然后调用
- 方法2将所有遵守协议SwizzleProtocol的类遍历 调用协议方法
// 001
extension ViewController {
static func yy_swizzle() {
guard let m1 = class_getInstanceMethod(self, #selector(viewWillAppear(_:))) else {
return
}
guard let m2 = class_getInstanceMethod(self, #selector(swizzle_viewWillAppear(_:))) else {
return
}
if (class_addMethod(self, #selector(swizzle_viewWillAppear(_:)), method_getImplementation(m2), method_getTypeEncoding(m2))) {
class_replaceMethod(self, #selector(swizzle_viewWillAppear(_:)), method_getImplementation(m1), method_getTypeEncoding(m1))
} else {
method_exchangeImplementations(m1, m2)
}
}
@objc func swizzle_viewWillAppear(_ animated: Bool) {
swizzle_viewWillAppear(animated)
print("swizzle_viewWillAppear")
}
}
/*
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
ViewController.yy_swizzle()
return true
}
*/
// 002
extension ViewController: SwizzleProtocol {
static func swizzle() {
guard let m1 = class_getInstanceMethod(self, #selector(viewWillAppear(_:))) else {
return
}
guard let m2 = class_getInstanceMethod(self, #selector(yy_viewWillAppear(_:))) else {
return
}
if (class_addMethod(self, #selector(yy_viewWillAppear(_:)), method_getImplementation(m2), method_getTypeEncoding(m2))) {
class_replaceMethod(self, #selector(yy_viewWillAppear(_:)), method_getImplementation(m1), method_getTypeEncoding(m1))
} else {
method_exchangeImplementations(m1, m2)
}
}
@objc func yy_viewWillAppear(_ animated: Bool) {
yy_viewWillAppear(animated)
print("yy_viewWillAppear")
}
}
protocol SwizzleProtocol {
static func swizzle()
}
class Swizzle {
// 获取到所有的类,遍历类,遵守协议AwakeProtocol的类执行awake方法
static func performOnce() {
let count = Int(objc_getClassList(nil, 0))
let classes = UnsafeMutablePointer<AnyClass?>.allocate(capacity: count)
let autoreleaseClasses = AutoreleasingUnsafeMutablePointer<AnyClass>(classes)
objc_getClassList(autoreleaseClasses, Int32(count))
for index in 0..<count {
(classes[index] as? SwizzleProtocol.Type)?.swizzle()
}
classes.deallocate()
}
}
/*
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
Swizzle.performOnce()
return true
}
*/
网友评论