首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift是否具有动态调度和虚拟方法?

Swift是否具有动态调度和虚拟方法?
EN

Stack Overflow用户
提问于 2014-06-03 19:29:49
回答 6查看 10.7K关注 0票数 27

出于C++/Java/C#背景,我希望在Swift中看到虚拟方法,但是在阅读swift文档时,我没有看到虚拟方法。

我遗漏了什么?

由于有大量的评论,我决定悬赏给一个最新的和非常清楚/详细的答案。

EN

回答 6

Stack Overflow用户

发布于 2014-08-22 09:23:46

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

(性能指标当然取决于硬件)

  • 内联方法:0 ns
  • 静态调度:<1.1 ns
  • 虚拟调度1.1 ns(指定时如Java、C#或C++ )。
  • 动态调度4.9(如Objective-C)。

当然,Objective-C总是使用后者。4.9 is的开销通常不是问题,因为这只占整个方法执行时间的一小部分。然而,在必要的地方,开发人员可以无缝地退回到C或C++。然而,在Swift中,编译器将分析哪些最快的可以使用,并试图代表您做出决定,支持内联、静态和虚拟,但保留用于Objective-C互操作性的消息传递。可以用dynamic标记一个方法来鼓励消息传递。

这样做的一个副作用是,动态分派提供的一些强大功能可能不可用,因为以前可以假设任何Objective-C方法都是这种情况。动态分派用于方法截获,方法截获由以下对象使用:

  • Cocoa风格的属性观察器。
  • CoreData模型对象检测。
  • Aspect Oriented Programming

上面的这些特性是由late binding语言提供的。请注意,虽然Java使用vtable分派进行方法调用,但它仍然被认为是一种后期绑定语言,因此由于具有虚拟机和类加载器系统(这是提供运行时插装的另一种方法),因此能够提供上述功能。“纯”Swift (没有Objective-C互操作)类似于C++,因为它是一种具有静态分派的直接到可执行的编译语言,那么这些动态功能在运行时是不可能的。在ARC的传统中,我们可能会看到更多这类功能转移到编译时间,这在“性能功耗比”方面提供了优势-移动计算中的一个重要考虑因素。

票数 21
EN

Stack Overflow用户

发布于 2014-06-03 19:52:54

所有方法都是虚拟的;但是,您需要使用override关键字声明您正在覆盖基类中的方法:

Swift Programming Guide

覆盖

子类可以提供它自己的实例方法、类方法、实例属性或下标的自定义实现,否则它将从超类继承。这就是所谓的覆盖。

要覆盖原本会被继承的特征,您可以在覆盖定义前面加上override关键字。这样做表明您打算提供覆盖,并且没有错误地提供匹配的定义。意外地重写可能会导致意外的行为,任何没有override关键字的重写都会在编译代码时被诊断为错误。

override关键字还提示Swift编译器检查覆盖类的超类(或其父类之一)是否具有与您为覆盖提供的声明相匹配的声明。此检查确保您的覆盖定义是正确的。

票数 7
EN

Stack Overflow用户

发布于 2014-06-05 05:16:30

代码语言:javascript
复制
class A {
    func visit(target: Target) {
        target.method(self);
    }
}

class B: A {}

class C: A {
    override func visit(target: Target) {
        target.method(self);
    }
}

class Target {
    func method(argument: A) {
        println("A");
    }

    func method(argument: B) {
        println("B");
    }

    func method(argument: C) {
        println("C");
    }
}

let t = Target();
let a:  A = A();
let ab: A = B();
let b:  B = B();
let ac: A = C();
let c:  C = C();

a.visit(t);
ab.visit(t);
b.visit(t);
ac.visit(t);
c.visit(t);

请注意ACvisit()中的self引用。就像在Java语言中一样,它不会被复制过来,相反,self会保持相同的类型,直到再次在覆盖中使用它。

结果是A,C,C,所以没有可用的动态调度。不幸的是。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24014045

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档