不要急,不要怕

runtime初体验--关联

对象关联(或称为关联引用)本来是Objective-C 2.0运行时的一个特性,起始于OS X Snow Leopard和iOS 4。相关参考可以查看 中定义的以下三个允许你将任何键值在运行时关联到对象上的函数:

objc_setAssociatedObject
objc_getAssociatedObject
objc_removeAssociatedObjects

他可以将某个OC对象通过一个唯一的key连接到一个类的实例上,这允许开发者对已经存在的类在扩展中添加自定义的属性,这几乎弥补了Objective-C最大的缺点。

举个栗子:

首先,引入#import

创建一个View
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(40,40 ,10 , 10)];
创建一个移动手势:

self.pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGesture:)];

将view和 颜色这两个属性添加到手势这个对象上:

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. */
};    

这里objc_AssociationPolicy是一个枚举类型的数据结构定义了OBJC_ASSOCIATION_ASSIGN、OBJC_ASSOCIATION_RETAIN_NONATOMIC、OBJC_ASSOCIATION_COPY_NONATOMIC、
OBJC_ASSOCIATION_RETAIN和
OBJC_ASSOCIATION_COPY这样五个关联对象特性,每个特性的描述如下:

OBJC_ASSOCIATION_ASSIGN,给关联对象指定弱引用,相当于@property(assign)或@property(unsafe_unretained)

OBJC_ASSOCIATION_RETAIN_NONATOMIC,给关联对象指定非原子的强引用,相当于@property(nonatomic,strong)或@property(nonatomic,retain)

OBJC_ASSOCIATION_COPY_NONATOMIC,给关联对象指定非原子的copy特性,相当于@property(nonatomic,copy)

OBJC_ASSOCIATION_RETAIN,给关联对象指定原子强引用,相当于@property(atomic,strong)或@property(atomic,retain)

OBJC_ASSOCIATION_COPY,给关联对象指定原子copy特性,相当于@property(atomic,copy)

objc_setAssociatedObject(self.pan, "firstObject", view, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(self.pan, "secondObject", view.backgroundColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC); OBJC_ASSOCIATION_RETAIN_NONATOMIC);

在手势移动的方法-(void)panGesture:(UIPanGestureRecognizer *)pan中实现:

UIView *view = objc_getAssociatedObject(pan, "firstObject");
    UIColor *color = objc_getAssociatedObject(pan, "secondObject");
     objc_removeAssociatedObjects(pan);

这样就的到了两个属性。什么,通过view.backgroundcolor就可以直接得到这两个属性了?只是个例子,目的是要看懂!!get,set有没有很熟悉呢?

需要注意的是objc_removeAssociatedObjects 函数我们一般是用不上的,因为这个函数会移除一个对象的所有关联对象,将该对象恢复成“原始”状态。这样做就很有可能把别人添加的关联对象也一并移除,这并不是我们所希望的。所以一般的做法是通过给 objc_setAssociatedObject 函数传入 nil 来移除某个已有的关联对象。