Since Xcode 11.4 static references to the type within a swizzled in method of a final class will resolve to the class whose method is being replaced. The issue can be reproduced in a playground with the following code:
import Foundation
class A: NSObject {
@objc dynamic func foo() {
}
}
final class B: NSObject {
@objc func swizzled_foo() {
print("Swizzled foo in \(B.self)")
}
}
method_exchangeImplementations(
class_getInstanceMethod(A.self, #selector(A.foo))!,
class_getInstanceMethod(B.self, #selector(B.swizzled_foo))!
)
A().foo()
In Xcode 11.3 Swizzled foo in B prints as expected but in Xcode 11.4 Swizzled foo in A is printed instead. Removing the final modifier from the B declaration resolves the issue but this doesn't look like an expected behavior.
1 Like
jrose
(Jordan Rose)
2
I could see people arguing that swizzled_foo should also be dynamic if it's going to be invoked in "weird" ways, but I think just being @objc ought to be enough to inhibit this optimization. Please file a bug at https://bugs.swift.org!