【问题标题】:why static dispatch so quickly in swift为什么静态调度如此迅速
【发布时间】:2023-03-06 07:00:01
【问题描述】:

我知道类中有一个方法列表。而且我也知道动态调度的机制。但我对静态调度感到困惑。静态方法在哪里。静态方法是否在全局哈希表中。以及静态调度是如何工作的。流程是什么样的。

【问题讨论】:

    标签: swift static dispatch


    【解决方案1】:

    您混淆了两个独立的概念。

    静态分派是指在运行时调用方法体的方式。如果你有一个类可能有子类或任何你只知道它符合某个协议的对象,你必须使用动态调度,这意味着你必须在表中查找方法的地址(称为 vtable 或见证表),然后跳转到该位置。如果编译器确切地知道它拥有什么样的对象,例如structfinal 类或类中的final 方法,它知道该方法不能被覆盖,因此可以直接跳转到其地址而无需进行查找。

    声明为static 的方法是一种类型方法。它将在类型本身而不是类型的实例上调用,即在方法内部 self 指的是类型而不是类型的实例。

    static 方法不能被覆盖,所以编译器在编译时总是知道地址并且会为它们使用静态调度。不需要任何类型的哈希表或见证表。

    【讨论】:

    • 见证表用于结构对吗?如果我们有一个带有静态方法的协议并且有几个结构实现了它,那么见证表必须参与,对吧?
    • 就像你说的“如果编译器确切地知道什么......因此直接跳转到它的地址而不进行查找”,编译器如何知道地址或地址保存在哪里。我认为“跳转到vtable方法中的位置”也很快,为什么大家都说它复杂。 @JeremyP
    • @dowZhang 编译器可以知道方法的直接位置,因为它要么刚刚编译了方法(或将要编译它),要么知道它是从另一个模块链接的,并且模块的元数据会告诉链接器正是方法所在的位置。只有当对象是类实例并且方法可以被覆盖或者编译器只知道它是符合协议的对象时,编译器才知道方法的位置。
    猜你喜欢
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 2020-12-20
    • 2018-11-11
    • 2016-11-28
    • 1970-01-01
    相关资源
    最近更新 更多