Что такое диспетчеризация методов и зачем она нужна?

Ответ

Диспетчеризация (method dispatch) – это механизм, который определяет, какая конкретная реализация метода должна быть выполнена при его вызове. Это основа полиморфизма в ООП.

Основные типы в Swift/iOS:

Тип диспетчеризации Как работает Преимущества Недостатки Пример в Swift
Статическая (Прямая) Компилятор напрямую указывает адрес функции в машинном коде. Максимальная скорость выполнения, оптимизация (inlining). Отсутствие полиморфизма. final методы, struct методы, глобальные функции.
Динамическая (Через таблицу) Вызов идет через таблицу виртуальных методов (vtable) класса. Решение принимается в runtime. Поддержка наследования и полиморфизма. Небольшие накладные расходы на поиск в таблице. Обычные методы class (не final).
Динамическая (Сообщения, Objective-C) Используется механизм objc_msgSend. Можно добавлять/менять методы в runtime. Гибкость (KVO, swizzling). Наибольшие накладные расходы. Методы, помеченные @objc или dynamic.

Практический пример полиморфизма через динамическую диспетчеризацию:

class Shape {
    func draw() { print("Drawing a generic shape") } // Диспетчеризация через vtable
}

class Circle: Shape {
    override func draw() { print("Drawing a circle") } // Своя запись в vtable
}

let shape: Shape = Circle() // Переменная типа Shape, значение типа Circle
shape.draw() // Выведет "Drawing a circle".
// Решение о вызове Circle.draw() принято в runtime благодаря динамической диспетчеризации.

Выбор типа диспетчеризации влияет на производительность и гибкость дизайна системы.

Ответ 18+ 🔞

Слушай, ну вот объясняю тебе как есть, про эту вашу диспетчеризацию. Представь, ты в баре, и кричишь: «Эй, дайте пива!». Это как статическая диспетчеризация, блядь. Бармен сразу, без души, хватает бутылку самого дешёвого пойла — адрес функции известен заранее, всё быстро, но скучно, как у final метода или в struct. Никаких сюрпризов, нихуя.

А теперь ситуация: ты орёшь: «Эй, принесите чего покрепче!». И вот тут начинается, ёпта, динамика через таблицу. Бармен смотрит в свою табличку (vtable, блядь), где у него записано: «если клиент — студент, то самогон; если бомж — стеклоочиститель; если бизнесмен — коньяк». Решение принимается прям в момент, когда ты уже протянул руку. Это и есть обычные методы класса в Swift. Скорость чуть меньше, зато полиморфизм, мать его, работает — можно подсунуть наследника, и он своё отработает.

Ну а самый треш, сука, это диспетчеризация через сообщения, как в Objective-C. Ты заходишь в этот же бар и заявляешь: «Слушай, сделай мне коктейль «Удар по печени с сюрпризом»!». Бармен, ебать, вообще в ступоре. У него в книге рецептов такого нет! Но система (runtime, блядь) такая гибкая, что он может на ходу, в runtime, позвать другого бармена, добавить ингредиент или вообще подменить тебе стакан на пустой. Мощно? Мощно. Но медленно, пиздец как медленно. Это методы с @objc или dynamic.

Короче, табличка для наглядности, чтобы не ебал мозг:

Тип диспетчеризации Как работает Плюсы Минусы Где в Swift
Статическая (Прямая) Компилятор тычет пальцем в конкретный адрес в памяти. Быстро, как удар током. Полиморфизма ноль, полный швах. final методы, struct, обычные функции.
Динамическая (Таблица) Бежит смотреть в святую табличку (vtable) во время выполнения. Наследование, переопределение — красота. Чуть-чуть тормозит, ищет строчку. Обычные методы класса.
Динамическая (Сообщения, Obj-C) Кричит objc_msgSend и ищет метод хоть у соседа. Полная хуйня творится в runtime, можно всё. Медленно, овердохуища накладных расходов. Всё, что помечено @objc или dynamic.

А вот живой пример, чтобы въехал, как это работает на практике:

class Shape {
    func draw() { print("Рисую какую-то хуйню") } // Запись в vtable
}

class Circle: Shape {
    override func draw() { print("Рисую круг, блядь") } // Своя запись в той же таблице
}

let shape: Shape = Circle() // Тип в объявлении — родитель, а внутри — ребёнок.
shape.draw() // Напечатает "Рисую круг, блядь".
// В runtime система смотрит в таблицу, видит, что там на самом деле Circle, и вызывает его метод. Вот и вся магия!

Так что выбирай, сука, что тебе важнее: скорость, как у ракеты, или гибкость, чтобы можно было на лету жонглировать методами. Всё есть компромисс, блядь.