Что такое Message Dispatch в Swift/Objective-C и приведите пример?

«Что такое Message Dispatch в Swift/Objective-C и приведите пример?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Message Dispatch (диспетчеризация сообщений) — это механизм динамического вызова методов в Objective-C runtime, где выбор реализации метода происходит во время выполнения программы путем отправки "сообщения" (селектора) объекту.

Ключевые особенности:

  • Самая гибкая, но самая медленная форма диспетчеризации.
  • Позволяет динамически добавлять/менять методы (method swizzling).
  • Поддерживает forwardInvocation: для обработки вызовов несуществующих методов.

Пример в Swift (с использованием @objc dynamic):

import Foundation

// Класс должен наследоваться от NSObject для работы с Objective-C runtime
@objc class DynamicSpeaker: NSObject {
    // Модификатор `dynamic` заставляет использовать message dispatch
    @objc dynamic func greet() {
        print("Hello from DynamicSpeaker")
    }
}

let speaker = DynamicSpeaker()

// 1. Прямой вызов (все равно будет через message dispatch из-за `dynamic`)
speaker.greet()

// 2. Вызов через селектор (явная отправка сообщения)
let selector = #selector(DynamicSpeaker.greet)
speaker.perform(selector)

// 3. Динамическое изменение реализации метода во время выполнения (method swizzling)
let originalMethod = class_getInstanceMethod(DynamicSpeaker.self, #selector(DynamicSpeaker.greet))!
let swizzledMethod = class_getInstanceMethod(DynamicSpeaker.self, #selector(swizzledGreet))!
method_exchangeImplementations(originalMethod, swizzledMethod)

speaker.greet() // Теперь вызовется swizzledGreet
Сравнение с другими типами диспетчеризации в Swift: Тип Скорость Где используется
Static (Direct) Самый быстрый struct, final class, private методы
Table (Virtual) Средняя Обычные методы в class (vtable)
Message Самый медленный @objc dynamic методы, Objective-C