objc_setAssociatedObject()
- 设置关联对象
用于给对象添加关联对象,传入 nil
则可以移除已有的关联对象;
让一个对象和另一个对象关联起来,即一个对象保持对另一个对象的引用,并可以获取这个对象。关键字是一个 void 类型的指针。每个关键字必须是唯一的,通常都是会采用静态变量来作为关键字。
/**
* Sets an associated value for a given object using a given key and association policy.
*
* @param object 关联的源对象.
* @param key 关联的key.
* @param value 通过key值关联对象,通过将此个值置成nil来清除关联.
* @param policy 关联策略
*
* @see objc_setAssociatedObject
* @see objc_removeAssociatedObjects
*/
OBJC_EXPORT void
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,
id _Nullable value, objc_AssociationPolicy policy)
OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0);
objc_getAssociatedObject () - 获取关联对象
用于获取关联对象;
/**
* Returns the value associated with a given object for a given key.
* 返回与给定键的给定对象关联的值
*
* @param object The source object for the association.
* @param key The key for the association.
*
* @return The value associated with the key \e key for \e object.
*
* @see objc_setAssociatedObject
*/
OBJC_EXPORT id _Nullable
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key)
OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0);
objc_removeAssociatedObjects () - 移除所有关联对象
用于移除一个对象的所有关联对象。
/**
* Removes all associations for a given object.
*
* @param object An object that maintains associated objects.
*
* @note The main purpose of this function is to make it easy to return an object
* to a "pristine state”. You should not use this function for general removal of
* associations from objects, since it also removes associations that other clients
* may have added to the object. Typically you should use \c objc_setAssociatedObject
* with a nil value to clear an association.
*
* ⚠️ 此函数的主要目的是使对象返回 “原始状态” 变得更容易。
* 你不应该使用此函数来从对象中删除关联,因为它还会删除其他客户端可能添加到对象的关联。
* 通常,你应该使用带有 nil 值的 objc_setAssociatedObject 方法来移除你的关联。
*
* @see objc_setAssociatedObject
* @see objc_getAssociatedObject
*/
OBJC_EXPORT void
objc_removeAssociatedObjects(id _Nonnull object)
OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0);
注:objc_removeAssociatedObjects
函数我们一般是用不上的,因为这个函数会移除一个对象的所有关联对象,将该对象恢复成 “原始” 状态。这样做就很有可能把别人添加的关联对象也一并移除,这并不是我们所希望的。所以一般的做法是通过给 objc_setAssociatedObject
函数传入 nil
来移除某个已有的关联对象。
objc_AssociationPolicy - 关联策略
/* Associative References */
/**
* Policies related to associative references.
* These are options to objc_setAssociatedObject()
*/
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
OBJC_ASSOCIATION_ASSIGN = 0, /** 弱引用关联对象 */
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /** 强引用关联对象,且为非原子操作. */
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, /** 复制关联对象,且为非原子操作 */
OBJC_ASSOCIATION_RETAIN = 01401, /** 强引用关联对象,且为原子操作 */
OBJC_ASSOCIATION_COPY = 01403 /** 复制关联对象,且为原子操作 */
};
示例一
需要先导入头文件:#import <objc/runtime.h>
//1.声明一个静态变量,用作关键字.此处也可以直接用一个字符串(但不推荐)
static char associatedKey;
//2.创建一个数组变量
NSArray *array = @[@"1", @"2"];
//3.创建一个字符串变量
NSString *value = @"hello sunshine";
// 设置关联对象
objc_setAssociatedObject(array, &associatedKey, value, OBJC_ASSOCIATION_RETAIN);
// 获取关联对象
NSString *associatedObject = (NSString *)objc_getAssociatedObject(array, &associatedKey);
NSLog(@"associatedObject:%@", associatedObject);
// 移除关联对象
objc_setAssociatedObject(array, &associatedKey, nil, OBJC_ASSOCIATION_ASSIGN);
输出结果:
testProject [20557:2739471] associatedObject:hello sunshine
参考
- objc_setAssociatedObject 使用
- 高效编写代码的方法 (二十一):Category (1)
- [Objective C] objc_setAssociatedObject 关联详解
- Objective-C Associated Objects 的实现原理
- Associated Objects @Mattt Thompson