将方法标记为@objc与动态之间的区别是什么,何时执行一个与另一个相比?
以下是Apple对动态的定义。
dynamic将此修饰符应用于可以的类的任何成员 由Objective-C表示。用标记成员声明时 动态修饰符,始终动态访问该成员 使用Objective-C运行时调度。访问该成员是 永远不会被编译器内联或虚拟化。
因为调度了使用动态修饰符标记的声明 使用Objective-C运行时,它们被隐式标记为objc 属性。
答案 0 :(得分:45)
声明为@objc
的函数/变量可从Objective-C访问,但Swift将继续通过静态或虚拟调度直接访问它。
这意味着如果通过Objective-C框架调整函数/变量,就像使用键值观察或各种Objective-C API修改类时所发生的那样,从Swift和Objective-C调用该方法将产生不同的结果。
使用dynamic
告诉Swift始终引用Objective-C动态调度。
这是Key-Value Observing等正常工作所必需的。调用Swift函数时,它引用Objective-C运行时来动态调度调用。
答案 1 :(得分:11)
正如该引言所说,dynamic
暗示@objc
。
除非您将类指定为dynamic
,否则编译器可以自由地优化并内联其方法。这带来了巨大的性能优势,但这意味着您无法在运行时更改这些方法实现。如果您计划使用Objective C运行时的反射功能在运行时使用这些方法,那么您需要使用dynamic
。您将承受性能损失(您的代码将以Objective C级别的速度运行,而不是接近C级别),但您将获得额外的动力。
答案 2 :(得分:1)
在处理互操作性时要记住两个关键词:
@objc
意味着您希望您的Swift代码(类,方法,属性等)在Objective-C中可见。dynamic
表示您想使用Objective-C dynamic dispatch. 在Swift 3和更早版本中,dynamic
也暗含@objc
。 Swift 4中的新增功能,dynamic
仅表示动态调度,而对Objective-C的可见性一无所知。
但是,没有 Swift 动态派发;我们只有 Objective-C 运行时的动态分配。这意味着您不能只具有动态性,而必须编写@objc dynamic
。因此,这实际上与以前一样,只是明确了。
了解更多here
答案 3 :(得分:0)
要使用Objective-C
中的Swift
,您至少要有两个保留字:
@objc
[About]-编译时间-要公开 Swift的用于 Objective-C运行时的api 。例如,在Swift上编写的框架可以将@objc
用于:
#selector
[About] dynamic
-运行时间-启用 message dispatch
对象的NSObject
(Objective-C的世界) ,它不同于virtual dispatch (table dispatch)
(Swift的世界)。它用于:
class extensions
有可能覆盖扩展功能在Swift v4
dynamic
之前包含@objc