Swift 3 - 动态vs @objc

时间:2016-11-24 23:40:30

标签: objective-c dynamic swift3

将方法标记为@objc与动态之间的区别是什么,何时执行一个与另一个相比?

以下是Apple对动态的定义。

  

dynamic将此修饰符应用于可以的类的任何成员   由Objective-C表示。用标记成员声明时   动态修饰符,始终动态访问该成员   使用Objective-C运行时调度。访问该成员是   永远不会被编译器内联或虚拟化。

     

因为调度了使用动态修饰符标记的声明   使用Objective-C运行时,它们被隐式标记为objc   属性。

4 个答案:

答案 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用于:

    1. 在Swift代码中使用#selector [About]
    2. 为Objective-C消费者开放公共功能
  • dynamic-运行时间-启用 message dispatch对象的NSObject(Objective-C的世界) ,它不同于virtual dispatch (table dispatch)(Swift的世界)。它用于:

    1. KVO
    2. class extensions有可能覆盖扩展功能
    3. 扑朔迷离[Example]

Swift v4 dynamic之前包含@objc