10
protocol A {
    func f()
}

struct S1 : A {
    func f() {
        print("S1")
    }
}

struct S2 : A {
    func f() {
        print("S2")
    }
}

let array: [A] = [S1(), S2()]

for s: A in array {
    s.f()
}

// "S1\n" "S2\n"

如果这是一个继承层次结构,我希望 Swift 使用 v-table 来查找正确的实现。但是,其中的具体类型array可以是任何实现A的,以及任何数量的其他协议,那么如果 Swift 运行时也使用 v-tables,它如何知道对象的结构呢?

4

1 回答 1

14

Swift 运行时使用一个 Protocol Witness Table,它包含指向每个类型的协议方法实现的指针。

Mike Ash 在他的文章Exploring Swift Memory Layout, Part II中解释得最好:

最后一个,在偏移量 32 处是底层类型和协议的“协议见证表”,其中包含指向协议方法的类型实现的指针。这就是编译器能够在运行时不知道底层类型的情况下对协议类型的值调用方法(例如 p())的方式。

我还会按照 Hamish 的评论中的建议观看 WWDC 视频理解 Swift 性能。

于 2016-07-12T15:32:27.673 回答