@objc关键字扩展子类行为

时间:2018-05-03 09:08:09

标签: swift swift4 swift4.1

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

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

 class MyClass {
 }

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

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

@objc关键字是否启用了邮件调度以及dynamic?或者不是?

1 个答案:

答案 0 :(得分:16)

  

@objc关键字是否启用了邮件调度以及dynamic

通常不会。通常,@objc属性本身只是将给定的类成员暴露给Objective-C - Swift仍可以使用表或静态分派自由地分派给它。如果您希望Swift在调用时使用消息调度,则需要将该成员标记为dynamic

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

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

  

但这不是NSObject实例。

在Apple平台(即具有Obj-C interop的平台)上,所有 Swift类都暴露给Obj-C运行时,并且所有隐式继承自一个名为{{的特殊Obj-C基类1}},符合_SwiftObject。因此,Swift类能够利用消息调度而无需继承NSObjectProtocol