Всем привет, с вами я, Наиль Габутдинов, iOS разработчик.  В разных языках программирования применяется механизм диспетчеризации методов (Method Dispatch), и все разработчики имеют с ним дело. Однако, не все это осознают и не все понимают, как этот механизм работает. Поэтому данная статья будет полезна всем разработчикам на Swift, которые хотят погрузиться глубже в диспетчеризацию методов и понять принципы ее работы, что в свою очередь позволит писать более эффективный код и избежать появления некоторых неочевидных проблем. Также статья будет полезна тем, кто в поисках работы – данный вопрос часто обсуждается на собеседованиях iOS разработчиков. Давайте разберемся, что же такое диспетчеризация, рассмотрим ее виды и случаи применения. По определению, диспетчеризация метода – это процесс выбора имплементации метода при его вызове – то есть процесс, который происходит между вызовом функции и ее выполнением, в ходе которого система определяет какую реализацию метода осуществить (если, к примеру, есть разные переопределения метода в дочерних классах или используются протоколы с их расширениями). В Swift нам доступно несколько видов диспетчеризации: Direct Dispatch (статическая),  Table Dispatch (динамическая), в свою очередь, делится на: Virtual Table, Witness Table, Message Dispatch (самая динамическая диспетчеризация). Давайте подробнее рассмотрим эти виды. Статическая/прямая диспетчеризация определяет однозначно реализацию метода уже на этапе компиляции, поэтому это самый быстрый тип диспетчеризации. Он используется в методах value типов (струтур), final классов, extension классов и протоколов. То есть, можно сделать вывод, что статическая диспетчеризация применяется, когда метод не может быть переопределен. Как следует из названия, в данном типе диспетчеризации формируется таблица с адресами методов сущности. Она создается на этапе компиляции, а сам адрес метода ищется по таблице уже во время runtime, что, само собой, сказывается на скорости работы в худшую строну. Рассмотрим два подвида табличной диспетчеризации. Virtual Table Данный тип диспетчеризации в основном используется для случаев наследования, то есть для классов. Для каждого класса и для каждого его сабкласса создается виртуальная таблица с адресами методов, при этом для дочернего класса эта таблица копируется вместе с адресами. В случае когда реализация метода полностью переходит из родительского класса, адрес в таблице наследника такой же (в примере ниже это метод method).Если какой-то метод переопределен через override (метод method1), то адрес меняется на другую реализацию. Ниже добавляются другие методы, которые добавились в этом сабклассе (method2). Ниже приведены достоинства и недостатки данного типа. Witness Table Witness Table выделен в Swift для работы с протоколами. В примере ниже для класса реализующего протокол NewProtocol создается отдельная таблица с адресами методов протокола, и при вызове метода у объекта с типом протокола NewProtocol используется Witness Table диспетчеризация. В случае реализации классом нескольких протоколов, для каждого протокола будет создаваться отдельная таблица. Отличие от Virtual Table заключается в отсутствии наследования. Message Dispatch — это самый динамичный вид диспетчеризации, который в основном используется в связке с Objective-C. Message Dispatch работает полностью в runtime. На примере ниже видим, что тоже присутствуют родительский и дочерний классы, но родительский класс при этом наследуется от NSObject. Для работы Message Dispatch, методу добавляется модификатор @objc dynamic. Для каждого класса тоже есть таблицы, но они, в отличии от Table Dispatch, не копируются при наследовании, в таблице дочернего класса есть ссылка super на родительский класс. При вызове метода у объекта дочернего класса, сначала идет поиск адреса у самого класса. Если не адрес не найден, то поиск продолжается у родительского класса, и так далее до NSObject. Еще одно отличие от Table Dispatch – все таблицы в этом виде диспетчеризации формируются в runtime, что значительно снижает скорость определения имплементации метода и делает его самым медленным. Message Dispatch лежит в основе KVO и KVC. Так как Message Dispatch работает в runtime, появляется возможность подменить реализацию методов — это называется Method Swizzling. Method Swizzling позволяет подменить метод другим в runtime, при этом оригинальная имплементация остается доступной. Ниже приведены плюсы и минусы данного типа диспетчеризации: В результате мы понимаем, что при вызове любого метода в Swift до его обработки есть еще процесс диспетчеризации, в ходе которого определяется нужная имплементация. Мы рассмотрели разные виды диспетчеризации и увидели, как отличается их работа и для каких типов объектов применима та или иная диспетчеризация. Ниже привожу таблицу, по которой можно понять, какая диспетчеризация будет в том или ином случае:  А также таблицу, в которой отображены способы управления видом диспетчеризации в зависимости от типа объекта: