Какие есть виды диспетчеризации методов в Swift?
Суть
Диспетчеризация — это способ, которым компилятор находит реализацию метода при вызове. В Swift их четыре, от самой быстрой к самой гибкой:
- Static (direct) — адрес функции известен на этапе компиляции. Так вызываются методы struct/enum,
final- иstatic-члены, методы из extension (кроме@objc), функции верхнего уровня. Позволяет инлайнинг и прочие оптимизации. - Table (vtable) — для методов классов, которые можно переопределить: у класса есть таблица указателей на методы, подкласс хранит свою копию с заменёнными указателями. Один индирект-переход, инлайнинг невозможен без девиртуализации.
- Table (witness table) — для вызовов через протокол (generic
T: Pбез специализации илиany P): таблица хранит, какая реализация у конкретного типа соответствует каждому требованию протокола. - Message (objc_msgSend) — через Objective-C runtime: метод ищется по селектору в рантайме. Включается у
@objc dynamicчленов и у@objc-методов в extensionNSObject-подклассов. Сам по себе@objcтолько экспортирует член в Obj-C — из Swift такой метод всё ещё вызывается через vtable.
Что именно выберет компилятор, зависит от типа переменной, через которую идёт вызов, и от места объявления метода (тело типа, extension, протокол).
Продолжение ответа с кодом и уточняющими вопросами интервьюера — в приложении DevPrep.
Полный ответ — в DevPrep