Can someone explain why @objc
keyword is needed here to compile the code?
As I understood this keyword is used in order to work ObjC message method dispatch. But this is not an NSObject
instance.
class MyClass {
}
extension MyClass {
@objc func extensionMethod() { /// THIS LINE
print("A")
}
}
class SubClass: MyClass {
override func extensionMethod() {
print("B")
}
}
Does @objc
keyword enable message dispatch as well as dynamic
? Or not?
Category and extension both are basically made to handle large code base, but category is a way to extend class API in multiple source files while extension is a way to add required methods outside the main interface file.
An extension can't be overridden because the way Swift implement extension is using static dispatch which means its resolved at compile time.
Objective-C source code 'messaging/implementation' program files usually have . m filename extensions, while Objective-C 'header/interface' files have . h extensions, the same as C header files.
Does
@objc
keyword enable message dispatch as well asdynamic
?
Not usually. Usually, the @objc
attribute on its own just exposes a given class member to Objective-C – Swift is still free to dispatch to it either using table or static dispatch. You would need to mark the member as dynamic
if you wanted Swift to use message dispatch when calling it.
However, for a non-final @objc
class extension member, Swift will automatically infer it to be dynamic
. Why? Because for interoperability reasons, Swift allows @objc
extension members to override and be overridden (much like how you can override an Obj-C method in a subclass category). In order to achieve this behaviour, Swift relies on Obj-C message dispatch.
Therefore, in an extension, @objc
infers dynamic
. You cannot override an extension member without exposing it to the Obj-C runtime because extension members cannot currently be added to Swift class vtables (as Swift vtables currently cannot have members dynamically added to them at runtime).
But this is not an
NSObject
instance.
On Apple platforms (i.e those with Obj-C interop), all Swift classes are exposed to the Obj-C runtime, and all implicitly inherit from a special Obj-C base class called _SwiftObject
, which conforms to NSObjectProtocol
. So Swift classes are able to take advantage of message dispatch without having to inherit from NSObject
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With