Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift是否对方法使用消息分派?_Swift - Fatal编程技术网

Swift是否对方法使用消息分派?

Swift是否对方法使用消息分派?,swift,Swift,我确信我的术语是错误的,所以这里有一个例子: C/C++有方法和虚拟方法。两者都有机会在编译时内联 C的CIL有调用< /COD>和 Calvirt < /Cuth>指令(它非常类似于C++方法和虚拟方法)。尽管C#中几乎所有的方法调用都变成了callvirt(由于langauge snafu),但JIT编译器能够优化大部分返回到call指令,然后(如果值得的话)将它们内联 Objective-C方法调用的方式非常不同(而且效率很低);每次调用方法时,消息对象都通过objc\u msgsen

我确信我的术语是错误的,所以这里有一个例子:

  • C/C++有方法和虚拟方法。两者都有机会在编译时内联
  • C的CIL有<代码>调用< /COD>和<代码> Calvirt < /Cuth>指令(它非常类似于C++方法和虚拟方法)。尽管C#中几乎所有的方法调用都变成了
    callvirt
    (由于langauge snafu),但JIT编译器能够优化大部分返回到
    call
    指令,然后(如果值得的话)将它们内联
  • Objective-C方法调用的方式非常不同(而且效率很低);每次调用方法时,消息对象都通过
    objc\u msgsend
    传递,这是一种动态分派形式,永远不能内联

阅读Swift的语言,我不知道Swift是否使用与Objective-C相同的消息传递系统或其他不同的消息传递系统。

有时是,有时不是。如果您使用纯Swift代码,并且不使用
@objc
装饰向Objective-C公开您的类/协议,看起来,纯swift方法调用不是通过
objc\u msgSend
发送的,但是在其他情况下是这样的。如果您的swift对象采用的协议在Objective-C中声明,或者如果swift协议用
@objc
修饰,则对协议方法的方法调用,即使是从swift对象到其他swift对象,也通过
objc\u msgSend
进行调度

目前文档有点单薄;我相信还有其他细微差别。。。但从经验上讲(即,我已经尝试过了),一些swift方法调用通过了objc\u msgSend,而另一些则没有。我认为获得最佳性能将取决于保持代码尽可能纯粹的swift,并尽可能少地跨越Obj-C/swift边界,以及通过瓶颈接口/协议,从而限制必须动态调度的swift调用数量


<> P> >我相信,以后会出现更详细的文档。

< P>与C++不同,不必指定一个方法在Swift中是虚拟的。编译器将确定使用以下哪一项:

性能指标当然取决于硬件

  • 内联方法:0 ns
  • 静态调度:<1.1ns
  • <>虚拟调度1.1NS(如java、C++或C++指定时)。<李>
  • 动态调度4.9ns(如Objective-C)
当然,Objective-C总是使用后者。4.9ns的开销通常不是问题,因为这只占整个方法执行时间的一小部分。但是,在必要的地方,开发者可以无缝地回到C或C++中。这在Swift中仍然是一个选项,但是编译器将分析可以使用哪一个最快,并尝试代表您做出决定

这样做的一个副作用是,动态调度提供的一些强大功能可能不可用,因为之前可以假设任何Objective-C方法都是如此。动态调度用于方法截取,而方法截取又由以下人员使用:

  • 可可风格的属性观察员
  • CoreData模型对象检测
  • 面向方面编程

在最新版本的Swift中,即使对象标记为“@objc”或扩展了NSObject,编译器也不一定使用动态分派。有一个动态属性可以添加到方法中以选择加入

Swift中没有像Objective-C中那样的“消息传递”概念。遗憾的是,Swift的实现已经结束,我不相信文档中有任何关于内部的内容可以回答您的问题。当编译器可以确定这样做是安全的时,Swift可能会进行优化以直接调用,但我认为这方面还没有任何可靠的文档。我认为如果您将func或属性定义为final,可能会有一个优化。因此,在这一点上,编译器将始终知道什么方法可以内联。