Swift 函数中的动态修饰符

Posted

技术标签:

【中文标题】Swift 函数中的动态修饰符【英文标题】:dynamic modifier in functions in Swift 【发布时间】:2015-04-16 21:42:58 【问题描述】:

根据苹果:

当您使用dynamic 修饰符标记成员声明时,始终动态分派对该成员的访问。因为使用 dynamic 修饰符标记的声明是使用 Objective-C 运行时调度的,所以它们被隐式标记为 @objc 属性。

根据***:

动态调度是选择在运行时调用哪个多态操作(方法或函数)实现的过程。

当不同的类由于共同继承而包含相同方法的不同实现时,动态分派通常用于面向对象的语言中。例如,假设您有类ABC,其中BC 都从A 继承方法foo()。现在假设x 是类A 的变量。在运行时,x 可能实际上有一个 BC 类型的值,通常在编译时您无法知道它是什么。

现在,我正在研究dependency injection 框架:Typhoon,当我在继承自Objective-C 类TyphoonAssembly 的所有类中打开Swift 的示例项目时,所有方法都与注入依赖项具有dynamic 修饰符,包含在以下方式中:

public dynamic func weatherReportDao() -> AnyObject 
    return TyphoonDefinition.withClass(WeatherReportDaoFileSystemImpl.self)

我以为我遗漏了一些东西,但我不明白 在运行时调用的多态操作(方法或函数)在哪里

动态调度的目的是什么?

【问题讨论】:

嗯,那里的文档有点奇怪。当世界上的大多数人,包括***,说“动态调度”时,它们通常是指来自重写类方法的运行时多态性。而在 Swift 中,这种情况不需要dynamic 关键字就可以发生,并且将在 100% 的时间里工作,尽管文档对内联和去虚拟化有什么暗语。但是在这里,当他们说动态时,他们的意思是那种疯狂的超动态运行时恶作剧,你可以通过 objc_msgSend-type 方法调度来解决。 在没有研究 Typhoon 的实现的情况下,他们可能决定使用动态调度来使其符合 KVO,以便在其他地方使用。 Michael Tsai 的博客在这里对dynamic 进行了有趣的讨论:http://mjtsai.com/blog/2014/08/18/its-a-coup/ 【参考方案1】:

这篇文章解决了您的问题:

https://github.com/appsquickly/typhoon/wiki/TyphoonAssembly

基本上在运行时,Typhoon Framework 会用自己的例程替换您的方法,该例程实现框架的功能并调用您的方法来完成您为其定义的任何工作。

为了让框架能够替换方法,方法必须是动态调度的。

【讨论】:

以上是关于Swift 函数中的动态修饰符的主要内容,如果未能解决你的问题,请参考以下文章

Swift中“withEvent”的含义,以及一般的参数修饰符

Swift 3:公共访问修饰符和内部访问修饰符之间的区别? [复制]

python中的修饰符@的作用

swift中填充修饰符的默认值是多少?

Java中的构造函数是不是有访问修饰符继承?

为啥 Swift 的访问修饰符默认不是私有的?