Ответ
Диспетчеризация — это механизм выбора конкретной реализации метода для вызова. В Swift представлены следующие типы (от самого быстрого к самому медленному):
-
Статическая (Static Dispatch)
- Решение принимается на этапе компиляции.
- Используется для: обычных функций,
struct/enumметодов,finalметодов и классов,privateметодов. - Пример:
struct Calculator { func add(_ a: Int, _ b: Int) -> Int { a + b } // Статическая диспетчеризация }
-
Диспетчеризация через таблицу свидетельств (Protocol Witness Table Dispatch)
- Используется для методов протоколов и обобщенных (
generic) контекстов. - Реализация выбирается в runtime на основе конкретного типа, соответствующего протоколу.
- Пример:
protocol Drawable { func draw() } struct Circle: Drawable { func draw() { print("Drawing circle") } } let shape: Drawable = Circle() shape.draw() // Вызов через PWT
- Используется для методов протоколов и обобщенных (
-
Динамическая диспетчеризация (Virtual Table Dispatch)
- Классический ООП-подход для нефинальных (
non-final) классов. - Решение принимается в runtime на основе типа объекта.
- Пример:
class Animal { func makeSound() { print("...") } } class Dog: Animal { override func makeSound() { print("Woof!") } } let pet: Animal = Dog() pet.makeSound() // Вызов через v-table -> "Woof!"
- Классический ООП-подход для нефинальных (
-
Диспетчеризация сообщений (Objective-C Message Dispatch)
- Полностью динамическая, используется только для элементов, помеченных
@objcиdynamic. - Позволяет делать method swizzling и отвечает на
responds(to:). - Пример:
class ObjCClass: NSObject { @objc dynamic func message() { print("Dynamic message") } }
- Полностью динамическая, используется только для элементов, помеченных