iOS Runtime - Associated Objects

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

参考

猜你喜欢

转载自blog.csdn.net/weixin_34128534/article/details/87036662