Вопрос проверяет знание оптимизаций Swift и понимание того, как ключевые слова и контекст влияют на выбор механизма вызова методов.
Да, в Swift можно добиться статической диспетчеризации у классов. Для этого используют final, приватные методы или отсутствие переопределений. В таких случаях компилятор знает точную реализацию метода заранее. Это позволяет избежать динамического вызова.
Хотя классы по умолчанию используют динамическую диспетчеризацию, Swift может оптимизировать этот механизм.
finalОпределение: final запрещает наследование или переопределение.
final class Logger {
func log() {
// реализация
}
}
Компилятор знает, что метод не может быть переопределён.
Методы с private или fileprivate:
недоступны для переопределения вне файла
могут быть статически задиспетчеризированы
class Service {
private func helper() {
// реализация
}
}
Если компилятор видит:
класс не наследуется
метод не переопределяется
он может применить devirtualization.
не гарантировано без final
зависит от оптимизаций компилятора
менее прозрачно для разработчика
Для гарантированной статической диспетчеризации у классов следует использовать final. Остальные способы — оптимизация, а не контракт.