Как во время выполнения Swift знает, какую реализацию использовать?
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-таблицу для поиска правильной реализации. Тем не менее, конкретные типы в array
может быть все, что реализует A
наряду с любым количеством других протоколов, как бы среда выполнения Swift узнала структуру объекта, если бы он также использовал v-таблицы?
1 ответ
Среда выполнения Swift использует таблицу свидетелей протокола, которая содержит указатели на реализации каждого типа методов протокола.
Майк Эш лучше всего объясняет это в своей статье " Изучение структуры памяти Swift, часть II:
Последний, по смещению 32, представляет собой "таблицу свидетелей протокола" для базового типа и протокола, которая содержит указатели на реализации типа методов протокола. Вот как компилятор может вызывать методы, такие как p(), для значения типа протокола, не зная базового типа во время выполнения.
Я также посмотрел бы видео WWDC " Понимание быстрой работы", как это было предложено в комментариях Хэмиша.