Расширьте свой класс:
extension YourClassName {
static let classInit: () -> () = {
let originalSelector = #selector(originalFunction)
let swizzledSelector = #selector(swizzledFunction)
swizzle(YourClassName.self, originalSelector, swizzledSelector)
}
@objc func swizzledFunction() {
//Your new implementation
}
}
Ваш класс (YourClassName
) должен наследовать от NSObject
, а originalSelector
должен быть методом dynamic
.
swizzle
это замыкание, которое обменивается реализациями:
private let swizzle: (AnyClass, Selector, Selector) -> () = { fromClass, originalSelector, swizzledSelector in
guard
let originalMethod = class_getInstanceMethod(fromClass, originalSelector),
let swizzledMethod = class_getInstanceMethod(fromClass, swizzledSelector)
else { return }
method_exchangeImplementations(originalMethod, swizzledMethod)
}
Вы можете определить swizzle
в классе, в котором вы собираетесь выполнять Swizzling.Например, определение класса AppDelegate
.И затем выполните swizzling в AppDelegate.init()
:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
override init() {
super.init()
YourClassName.classInit()
}
}
Example
Вот конкретный пример swizzling, он обменивается реализацией двух методовкоторые принимают один аргумент:
class Example: NSObject {
@objc dynamic func sayHi(to name: String) {
print("Hi", name)
}
}
extension Example {
public class func swizzleMethod() {
guard
let originalMethod = class_getInstanceMethod(Example.self, #selector(Example.sayHi(to:))),
let swizzledMethod = class_getInstanceMethod(Example.self, #selector(Example.sayHello(to:)))
else { return }
method_exchangeImplementations(originalMethod, swizzledMethod)
}
@objc func sayHello(to name: String) {
print("Hello", name)
}
}
Example.swizzleMethod()
let a = Example()
a.sayHi(to: "Nitish") //Hello Nitish