swift - @objc 关键字扩展子类行为
问题描述
有人可以解释为什么@objc
这里需要关键字来编译代码吗?
据我了解,此关键字用于工作 ObjC 消息方法分派。但这不是一个NSObject
例子。
class MyClass {
}
extension MyClass {
@objc func extensionMethod() { /// THIS LINE
print("A")
}
}
class SubClass: MyClass {
override func extensionMethod() {
print("B")
}
}
关键字是否@objc
也启用消息发送dynamic
?或不?
解决方案
关键字是否
@objc
也启用消息发送dynamic
?
通常不会。通常,@objc
属性本身只是将给定的类成员暴露给 Objective-C——Swift 仍然可以使用表或静态分派来自由地分派给它。您需要标记该成员,就dynamic
好像您希望 Swift 在调用它时使用消息调度一样。
但是,对于非 final@objc
类扩展成员,Swift 会自动将其推断为dynamic
. 为什么?因为出于互操作性的原因,Swift 允许@objc
扩展成员覆盖和被覆盖(很像如何覆盖子类类别中的 Obj-C 方法)。为了实现这种行为,Swift 依赖于 Obj-C 消息分发。
因此,在扩展中,@objc
推断dynamic
. 你不能覆盖扩展成员而不将其暴露给 Obj-C 运行时,因为扩展成员当前不能添加到 Swift 类 vtables(因为 Swift vtables 目前不能在运行时动态添加成员)。
但这不是一个
NSObject
例子。
在 Apple 平台上(即具有 Obj-C 互操作性的平台),所有Swift 类都暴露给 Obj-C 运行时,并且都隐式继承自一个特殊的 Obj-C 基类,称为_SwiftObject
,它符合NSObjectProtocol
. 因此 Swift 类能够利用消息调度,而无需继承自NSObject
.
推荐阅读
- javascript - 你如何让赛普拉斯选择列表中的某个图标?
- assembly - 为什么我不能将 64 位值移动到 64 位寄存器?
- docker - 如何在包括 localhost 机器的 docker 容器之间进行通信
- ios - 找不到支持键盘 iPhone-PortraitTruffle-DecimalPad 的 type 8 的键盘;
- html - 为什么空白:pre; 打破表格内的表格html?
- variables - 如何将地图的块地图转换为 Terraform 中的变量
- mysql - 简单插入记录时截断不正确的 DOUBLE 值
- php - 无需使用表单/POST 即可将信息传递给支付提供商的安全替代方式
- r - 文本分类,rnn包R
- c# - MVC:数据未从控制器传递到视图