Вопрос проверяет знание особенностей вызова методов протокола для финальных классов в Swift.
Даже в final классе методы, реализующие требования протокола, могут вызываться через динамическую диспетчеризацию при работе с типом протокола. Однако компилятор Swift применяет оптимизацию и в большинстве случаев заменяет такие вызовы на статические, если тип известен на этапе компиляции.
Вызовы по протоколу:
Когда объект хранится в переменной типа протокола, Swift использует witness table для поиска реализации.
Это похоже на виртуальную таблицу, но для протоколов.
Влияние final:
final class гарантирует, что реализация не изменится.
Компилятор может внутренне оптимизировать и при прямом доступе по конкретному типу обойти witness table.
Сценарии:
Переменная конкретного типа: прямой вызов статически.
Переменная типа протокола: обычно вызов через witness table (динамически).
Пример:
protocol Greeter {
func greet()
}
final class EnglishGreeter: Greeter {
func greet() { print("Hello") }
}
let greeter: Greeter = EnglishGreeter()
greeter.greet() // через witness tableВывод:
Для финальных классов Swift стремится к статической диспетчеризации, но при вызове через протокол остаётся использование механизма witness table.