2016-11-24 112 views
22

将方法标记为@objc与动态之间有什么区别,您会在何时与其他人做比较?Swift 3 - 动态与@objc

下面是苹果对动态的定义。

dynamic将此修饰符应用于可由Objective-C表示的 的任何成员。当您使用动态修饰符 标记成员声明时,对该成员的访问始终是动态使用Objective-C运行时分派的 。对该成员的访问权限是 ,不受编译器内联或虚拟化。

由于使用Objective-C运行时调度 ,因此使用动态修饰符标记的声明隐含标记为objc 属性。

+0

您的问题已回答? – Alexander

回答

26

声明为@objc的函数/变量可从Objective-C访问,但Swift将继续通过静态或虚拟调度直接访问它。 这意味着如果通过Objective-C框架调用函数/变量,就像使用Key-Value Observing或各种Objective-C API修改类时发生的情况一样,从Swift和Objective-C调用该方法将产生不同的结果。

使用dynamic告诉Swift始终引用Objective-C动态分派。 这是Key-Value Observing正常工作所必需的。当调用Swift函数时,它引用Objective-C运行时来动态分配调用。

+0

我不知道KVO正在被搅乱,你能详细说明这一点吗? – Boon

+2

@Boon KVO创建一个动态子类,用willChangeValueForKey/didChangeValueForKey调用包装的属性替换您的属性,除非使用自动忽略观察者关键字来选择退出。 – kevin

6

正如那句话所说,dynamic意味着@objc

除非您将类指定为dynamic,否则编译器可以自由优化并内联其方法。这带来了巨大的性能优势,但这意味着您无法在运行时更改这些方法实现。如果您打算在运行时使用Objective C运行时的反射功能来处理这些方法,则需要使用dynamic。你会得到一个性能损失(你的代码将运行在Objective C的速度级别,而不是接近类C级别),但是你会获得额外的活力。