I'm playing around with swizzling. I've written this code to exchange implementation for a method of a class with extension.
@objc class A: NSObject {
@objc func name() {
print("this is class A")
}
}
extension A {
@objc func myName() {
self.myName()
print("this is my extension version of A")
}
}
@objc class B: A {
@objc override func name() {
super.name()
}
@objc override func myName() {
super.myName()
}
}
// swizzling name and myName
let originalSelector = #selector(A.name)
let swizzledSelector = #selector(A.myName)
guard let swizzledMethod = class_getInstanceMethod(A.self, swizzledSelector) else {
fatalError()
}
if let originalMethod = class_getInstanceMethod(A.self, originalSelector) {
method_exchangeImplementations(originalMethod, swizzledMethod)
print("replaced")
}
now i run this code to test it:
let b = B()
print("-----")
b.name()
print("-----")
b.myName()
I expect this output:
replaced
-----
this is class A
this is my extension version of A
-----
this is class A
but what I actually see in log is this:
replaced
-----
this is class A
-----
this is class A
what I'm doing or expecting wrong?
Refer to swift method_exchangeImplementations not work
By adding the dynamic declaration modifier, the swizzling happens properly. Without this, the call to method_exchangeImplementations() does not have the intended effect. See https://swiftunboxed.com/interop/objc-dynamic/ for more information about dynamic dispatch.
So like this:
@objc dynamic func name() {
print("this is class A")
}