Найти тему
Даниил Зазулин

Swift. Диспетчеризация

Вся статья - это конспект видео с ютуба "Method Dispatch - Диспетчеризация методов в Swift", пишу для себя, так лучше запоминаю


Диспетчеризация - это процесс выбора имплементации метода при его вызове.

Виды диспетчеризации:

  • Static/Direct_ (статичная/прямая)
  • Table (табличная)

- Witness-table

- Virtual-table

  • Messages (на сообщениях) - Obj-C

Static/Direct_ - прямой вызов метода уже известный на этапе компиляции. То есть метод располагается где-то в памяти, при его вызове извлекается ссылка на этот метод, и начинается его выполнения

+ Самый быстрый тип диспетчеризации (0-2 ns)

- Не реализует полиморфизм и наследование

Table (табличная)

1) Witness-table - (про протоколы)

+ Медленее, чем Static/Direct_ (~3 ns)

+ Реализует полиморфизм

- Не реализует наследование

-2

Если класс реализует несколько протоколов, то для каждой такой реализации будет своя Witness-таблица.

2) Virtual-table- (про классы)

+ Медленее, чем Static/Direct_ (~3 ns)

+ Реализует полиморфизм

+ Реализует наследование

-3

Как видно method1 не изменился и ссылка у таблицы Child и Parent совпадают


Messages

+ KVC/KVO

+ Поддержка Swizzling методов

- Самый медленный ~ 5.82ns

В swift используется только для совместимости с obj-c runtime

-4

Работает в Runtime

Value type

Для всех value type для функций, если они не по реализации протокола, используется direct_ dispatch.

-5

Reference type

В обычном случае из-за того, что Reference type поддерживает наследование, то используется Virtual-table

-6

Reference type + Extensions

Вообще для всех extensions и для протоколов, структур и классов используется direct dispatch, кроме расширений для NSObject

-7

Пограничная ситуация

-8

Witness Table во втором случае, потому что кастим к протоколу и в основном тела протокола функция находится не в extension, в противном случае (то есть в extension) было бы то же Direct.

Так для класса, который помечен как final, используется прямая диспетчеризация - Direct dispatch, потому что final делается класс не наследуемым и соответственно не допускает полиморфизм

Обобщение

-9