一尘不染

@objc关键字扩展子类行为

swift

有人可以解释为什么@objc在这里需要关键字来编译代码吗?

据我了解,此关键字用于工作ObjC消息方法调度。但这不是一个NSObject实例。

 class MyClass {
 }

 extension MyClass {
     @objc func extensionMethod() { /// THIS LINE
         print("A")
     }
 }

 class SubClass: MyClass {
     override func extensionMethod() {
         print("B")
     }
 }

@objc关键字是否也启用消息分发dynamic?或不?


阅读 240

收藏
2020-07-07

共1个答案

一尘不染

@objc关键字是否也启用消息分发dynamic

通常不行。通常,@objc属性本身只是将给定的类成员暴露给Objective-C –
Swift仍然可以使用表或静态分派自由地对其进行分派。您需要标记该成员,dynamic就像您希望Swift在调用它时使用消息分发一样。

但是,对于非最终@objc扩展
成员,Swift会自动将其推断为dynamic。为什么?因为出于互操作性的原因,Swift允许@objc扩展成员覆盖和覆盖(就像您可以在子类类别中覆盖Obj-
C方法一样)。为了实现此行为,Swift依赖于Obj-C消息调度。

因此,在扩展中,@objc推断dynamic。您不能覆盖扩展成员而不将其暴露给Obj-
C运行时,因为扩展成员当前无法添加到Swift类vtable(因为Swift vtable当前不能在运行时动态地将成员添加到它们)。

但这不是一个NSObject实例。

在Apple平台上(即具有Obj-C互操作的平台), 所有 Swift类都向Obj-C运行时公开,并且所有隐式继承自名为的特殊Obj-
C基类_SwiftObject,该基类与一致NSObjectProtocol。因此,Swift类无需继承自就能利用消息分发的优势NSObject

2020-07-07