Ответ
Нет. Хотя для прямых вызовов методов структуры или перечисления компилятор обычно использует статическую диспетчеризацию (прямой вызов по известному адресу в compile-time), есть случаи применения динамической диспетчеризации.
Когда используется динамическая диспетчеризация:
- При работе через протокол (Protocol Witness Table - PWT): Когда экземпляр value type приводится к типу протокола.
- При использовании модификатора
@objc: Если метод помечен@objc(например, для совместимости с KVO или Objective-C runtime). - При использовании ключевого слова
dynamic: Явное указание на необходимость динамической диспетчеризации.
Пример динамической диспетчеризации через протокол:
protocol Renderable {
func render()
}
struct Button: Renderable {
// Статическая диспетчеризация при прямом вызове: `Button().render()`
// Динамическая диспетчеризация при вызове через протокол
func render() { print("Rendering button") }
}
let renderableItem: Renderable = Button() // Тип — existential контейнер
renderableItem.render() // Диспетчеризация через Protocol Witness Table (PWT)
Итог: Статическая диспетчеризация — это оптимизация по умолчанию для value types, но семантика протоколов и взаимодействие с Objective-C runtime могут переключить ее на динамическую.