Ответ
Методы, объявленные в extension, используют статическую диспетчеризацию (static dispatch). Компилятор определяет конкретную реализацию для вызова на этапе компиляции.
Причина: extensions не могут переопределять существующие методы в исходном типе — они только добавляют новую функциональность. Поэтому для них не требуется динамическая диспетчеризация (v-table).
Пример, демонстрирующий разницу:
class BaseClass {
func original() { print("Base: original") }
func extensible() { print("Base: extensible") }
}
extension BaseClass {
func added() { print("Extension: added") }
func extensible() { print("Extension: extensible") } // НЕ переопределение!
}
let instance: BaseClass = BaseClass()
instance.original() // Динамическая диспетчеризация
instance.added() // Статическая диспетчеризация
instance.extensible() // Вызовется метод из класса, а не из extension
Исключения и нюансы:
- Для
@objcметодов в extension классов диспетчеризация становится динамической через Objective-C runtime. - Протоколы с реализацией по умолчанию в extension также используют статическую диспетчеризацию для этих реализаций.