Что такое swizzling? В чем его преимущества/недостатки?ios-52

Swizzling — это техника в Objective-C и Swift (через динамическую диспетчеризацию Objective-C), которая позволяет изменять реализацию методов во время выполнения (runtime). Это достигается путем подмены селекторов (SEL) и их реализаций (IMP) в таблице методов класса.

Как работает swizzling?

  1. Таблица методов (Method Table): Каждый класс в Objective-C имеет таблицу методов, где хранятся соответствия между селекторами (SEL) и реализациями (IMP).
  2. Подмена IMP: Swizzling меняет местами IMP двух методов, так что при вызове оригинального метода выполняется новая реализация, и наоборот.

Пример кода на Objective-C:

// Original method
- (void)originalMethod {
    NSLog(@"Original implementation");
}

// Swizzled method
- (void)swizzledMethod {
    NSLog(@"Swizzled implementation");
    [self swizzledMethod]; // Вызовет оригинальную реализацию
}

// Swizzling
Method originalMethod = class_getInstanceMethod([self class], @selector(originalMethod));
Method swizzledMethod = class_getInstanceMethod([self class], @selector(swizzledMethod));

method_exchangeImplementations(originalMethod, swizzledMethod);

Преимущества swizzling

  1. Гибкость: Позволяет модифицировать поведение системных или сторонних классов без изменения их исходного кода.
  2. Динамичность: Изменения применяются во время выполнения, что полезно для отладки, логирования или A/B тестирования.
  3. Мощь для хакинга: Используется в библиотеках (например, для трекинга событий, мокания сетевых запросов).

Недостатки swizzling

  1. Сложность отладки: Неочевидное поведение кода, так как изменения не видны в исходниках.
  2. Хрупкость: Может сломаться при обновлении iOS или сторонних библиотек (если изменится внутренняя реализация методов).
  3. Конфликты: Если несколько библиотек делают swizzling одного и того же метода, результат непредсказуем.
  4. Нарушение инкапсуляции: Прямое вмешательство в чужой код может привести к неожиданным сайд-эффектам.

Когда использовать swizzling?

  • Для отладки (логирование вызовов методов).
  • Для исправления багов в системных классах (например, исправление поведения UIKit).
  • В библиотеках, где иначе невозможно достичь нужной функциональности.

Альтернативы swizzling

  1. Категории (Categories): Более безопасный способ расширения функциональности классов.
  2. Делегирование: Если API поддерживает делегаты, лучше использовать их.
  3. Наследование: Создание подклассов для модификации поведения.

Резюмируем

Swizzling — мощный, но опасный инструмент. Он дает гибкость, но требует осторожности. Используйте его только когда другие методы недоступны, и всегда документируйте такие изменения. В Swift старайтесь избегать swizzling, так как он работает только с @objc методами и нарушает безопасность типов.