OC的AssociatedObject
- Associated Object 指一个关联的对象,把一个key-object对和一个已有的特定对象关联起来。比如有一个对象A,和另一个对象B,我们可以找一个合适的key,让他们之间产生关系。在已知A的情况下,我们通过key就能找到和A关联起来的B对象。
// 我们来看下运行时库提供的方法 //1 源对象object //2 关键字 唯一静态变量key //3 关联的对象 value //4 关键策略 objc_AssociationPolicy policy void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) id objc_getAssociatedObject(id object, const void *key)
//objc_AssociationPolicy类型的参数,这个是与内存策略有关,就好比在@property后面的属性说明assign、retain、copy等。其中包括了如下值:
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) { OBJC_ASSOCIATION_ASSIGN = 0, // 指定对关联的对象的弱引用。
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, // 指定关联的对象的强引用。
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. */ };
- 了解了这么多, 接下来我们看看如何使用AssociatedObjects:
例子1: 假设现在已有class A,现在要对A类做扩展,我可以写一个A的Category,增加一个property,比如叫name。
@interface A(GCExtension) @property (nonatomic,copy) NSString * name; @end static void *nameKey = "nameKey"; @implementation A(GCExtension) -(void)setName:(NSString*)name { objc_setAssociatedObject(self, nameKey, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -(NSString*)name { return objc_getAssociatedObject(self, nameKey); } @end
//使用函数objc_removeAssociatedObjects可以断开所有关联。通常情况下不建议使用这个函数,因为他会断开所有关联。只有在需要把对象恢复到“原始状态”的时候才会使用这个函数。
例子2:利用runtime给UIButton添加一个按钮重复点击间隔的属性