Вот список вариантов использования для ассоциаций объектов:
one: Чтобы добавить переменные экземпляра в категории. В общем, этот метод рекомендуется против, но вот пример законного использования. Допустим, вы хотите смоделировать дополнительные переменные экземпляра для объектов, которые вы не можете изменить (мы говорим об изменении самого объекта, то есть без подклассов). Допустим, установка заголовка на UIImage.
// UIImage-Title.h:
@interface UIImage(Title)
@property(nonatomic, copy) NSString *title;
@end
// UIImage-Title.m:
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
static char titleKey;
@implementation UIImage(Title)
- (NSString *)title
{
return objc_getAssociatedObject(self, &titleKey);
}
- (void)setTitle:(NSString *)title
{
objc_setAssociatedObject(self, &titleKey, title, OBJC_ASSOCIATION_COPY);
}
@end
Кроме того, здесь - довольно сложный (но потрясающий) способ использования связанных объектов с категориями ... он в основном позволяет передавать блок вместо * селектора в UIControl
.
two: Динамическое добавление информации о состоянии к объекту, не охватываемому его переменными экземпляра, в сочетании с KVO.
Идея состоит в том, что ваш объект получает информацию о состоянии только во время выполнения (т. Е. Динамически). Таким образом, идея заключается в том, что хотя вы можете хранить эту информацию о состоянии в переменной экземпляра, тот факт, что вы присоединяете эту информацию к объекту, созданному во время выполнения, и динамически связываете его с другим объектом, вы подчеркиваете тот факт, что это динамическое состояние объекта.
Один прекрасный пример, иллюстрирующий это, - это эта библиотека, в которой ассоциативные объекты используются с KVO уведомлениями. Вот выдержка из кода (примечание: это уведомление KVO не нужно для запуска, чтобы код в этой библиотеке работал ... скорее, он помещен туда автором для удобства, в основном, любой объект, который регистрируется в этом, будет уведомлен через KVO что с ним произошло):
static char BOOLRevealing;
- (BOOL)isRevealing
{
return [(NSNumber*)objc_getAssociatedObject(self, &BOOLRevealing) boolValue];
}
- (void)_setRevealing:(BOOL)revealing
{
[self willChangeValueForKey:@"isRevealing"];
objc_setAssociatedObject(self, &BOOLRevealing,
[NSNumber numberWithBool:revealing], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self didChangeValueForKey:@"isRevealing"];
}
бонус: взгляните на это обсуждение / объяснение связанных объектов Мэттом Томпсоном, автором оригинальной библиотеки AFNetworking