Обзор
Категории и расширения — это два механизма Objective-C для добавления функциональности в существующие классы, но они служат разным целям и имеют различные ограничения.
Категории
- Позволяют добавлять методы в любой существующий класс, включая классы, которые тебе не принадлежат (например,
NSString, UIViewController)
- Могут быть определены в отдельных файлах и подгружаться во время выполнения
- Не могут добавлять хранимые свойства — поддерживаются только методы
- Обычно используются для организации кода или расширения системных классов
@interface NSString (MyCategory)
- (BOOL)isPalindrome;
@end
Расширения класса
- Также известны как анонимные категории (объявляются с пустыми скобками)
- Требуют доступа к исходному коду на этапе компиляции
- Могут добавлять хранимые свойства и приватные переменные экземпляра
- Используются в основном для объявления приватных методов и свойств, скрытых от публичного интерфейса
@interface MyClass ()
@property (nonatomic, strong) NSString *privateData;
- (void)privateMethod;
@end
Ключевые различия
- Применимость: категории работают с любым классом; расширения требуют исходного кода
- Свойства: только расширения поддерживают хранимые свойства
- Видимость: расширения используют для приватной инкапсуляции; категории — для публичного расширения функциональности
- Время жизни: категории разрешаются во время выполнения; расширения компилируются непосредственно в класс
Важное замечание
Попытка добавить хранимое свойство через категорию — распространённая ошибка, которая приведёт к ошибке компилятора. Обходной вариант — использование objc_setAssociatedObject, но прибегать к нему не рекомендуется без крайней необходимости.