Когда используется статическая диспетчеризация (Static Dispatch) в Swift?

«Когда используется статическая диспетчеризация (Static Dispatch) в Swift?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Static Dispatch (прямой вызов) используется, когда компилятор может однозначно определить, какая реализация метода должна быть выполнена, на этапе компиляции.

Условия для Static Dispatch:

  1. Методы структур и перечислений: Все методы value types используют статическую диспетчеризацию.
  2. final методы и классы: Классы или методы, помеченные ключевым словом final, не могут быть переопределены.
  3. private и fileprivate методы: Если метод не виден за пределами файла/объявления, компилятор гарантирует отсутствие переопределений.
  4. Методы, не входящие в протокол или не переопределенные: В классах, где полиморфизм не задействован.

Пример:

struct MyStruct {
    func work() { print("Struct work") } // Static Dispatch
}

final class FinalClass {
    func work() { print("Final class work") } // Static Dispatch
}

class Parent {
    private func hidden() {} // Static Dispatch
    func normal() {} // *Может* быть Dynamic Dispatch, если класс не final
}

let myStruct = MyStruct()
myStruct.work() // Компилятор напрямую вставляет вызов `MyStruct.work`

Преимущество: Исключаются накладные расходы на поиск в таблице виртуальных методов (vtable), что делает вызов быстрее и позволяет проводить агрессивные оптимизации (инлайнинг).