概念
从字面上理解就是将一个对象关联到另一个对象上,在 <objc/runtime.h> 中定义的以下三个函数允许你将任何键值在运行时关联到对象上。
objc_setAssociatedObject
objc_getAssociatedObject
objc_removeAssociatedObjects
应用场景
这样做有什么好处呢,在 Objective-C 中可以通过 Category 给一个现有的类添加属性,但是却不能添加实例变量,使用关联对象可以来弥补这一不足。
Matt总结的应用场景有:
- 添加私有属性用于更好地去实现细节
- 添加public属性来增强category的功能
- 创建一个用于KVO的关联观察者
如何使用
- 设置关联对象
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
该函数以给定的键和策略为某对象设置关联对象值,value传入nil可以移除已有的关联对象
- 获取关联对象
id objc_getAssociatedObject(id object, const void *key)
该函数依据给定键从某对象当中获取关联对象值
- 移除所有关联对象
void objc_removeAssociatedObjects(id object)
该函数移除指定对象的全部关联对象的值。此函数的主要目的是在“初试状态”时方便地返回一个对象。你不应该用这个函数来删除对象的属性,因为可能会导致其他客户对其添加的属性也被移除了。规范的方法是:调用 objc_setAssociatedObject 方法并传入一个 nil 值来清除一个关联。
关联规则
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
OBJC_ASSOCIATION_ASSIGN = 0, /**< Specifies a weak reference to the associated object. */
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object.
* The association is not made atomically. */
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, /**< Specifies that the associated object is copied.
* The association is not made atomically. */
OBJC_ASSOCIATION_RETAIN = 01401, /**< Specifies a strong reference to the associated object.
* The association is made atomically. */
OBJC_ASSOCIATION_COPY = 01403 /**< Specifies that the associated object is copied.
* The association is made atomically. */
};
关联规则命名同内存管理语义的命名一致,
实现原理
举例
在分类中添加属性
@property (strong, nonatomic) NSString *associatedObject_retain;
- (NSString *)associatedObject_retain {
return objc_getAssociatedObject(self, _cmd);
}
- (void)setAssociatedObject_retain:(NSString *)associatedObject_retain {
objc_setAssociatedObject(self, @selector(associatedObject_retain), associatedObject_retain, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
参考
NSHisper:Associated Objects
Objective-C Associated Objects 的实现原理
关联对象 AssociatedObject 完全解析
网友评论