Associated Objects(关联对象)或者叫做关联引用(Associated References),是作为Objective-C 2.0运行时功能被引入到Mac OS 10.6 Snow Leopard(及iOS4)系统。与它相关在<objc/rumtime.h>中有3个C函数,他们可以让对象在运行时关联任何值
(1)用给定的key和policy来为指定对象(object)设置关联对象值(value)
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
(2)根据给定的key从指定对象(object)中获取相对应的关联对象值
id objc_getAssociatedObject(id object, const void *key)
(3)移除指定对象的全部关联对象
void objc_removeAssociatedObjects(id object)
开发者可以通过上面的几个函数在分类中给已存在的类中添加自定义的属性,手动添加getter和setter
关联对象的特性
在#import <objc/runtime.h>中关于objc_AssociationPolicy的定义如下
OC版
enum {
OBJC_ASSOCIATION_ASSIGN = 0,
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
OBJC_ASSOCIATION_RETAIN = 01401,
OBJC_ASSOCIATION_COPY = 01403
};
typedef uintptr_t objc_AssociationPolicy;
swift版
/**
* Policies related to associative references.
* These are options to objc_setAssociatedObject()
*/
public enum objc_AssociationPolicy : UInt {
/**< Specifies a weak reference to the associated object. */
case OBJC_ASSOCIATION_ASSIGN
/**< Specifies a strong reference to the associated object.
* The association is not made atomically. */
case OBJC_ASSOCIATION_RETAIN_NONATOMIC
/**< Specifies that the associated object is copied.
* The association is not made atomically. */
case OBJC_ASSOCIATION_COPY_NONATOMIC
/**< Specifies a strong reference to the associated object.
* The association is made atomically. */
case OBJC_ASSOCIATION_RETAIN
/**< Specifies that the associated object is copied.
* The association is made atomically. */
case OBJC_ASSOCIATION_COPY
}
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)
示例代码 创建一个NSObject名为AssociatedObject的Category,向其中关联一个叫做associatedObject的属性。
NSObject+AssociatedObject.h
@interface NSObject (AssociatedObject)
@property (nonatomic, strong) id associatedObject;
@end
NSObject+AssociatedObject.m
@implementation NSObject (AssociatedObject)
@dynamic associatedObject;
- (void)setAssociatedObject:(id)object
{
objc_setAssociatedObject(self, @selector(associatedObject), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (id)associatedObject
{
return objc_getAssociatedObject(self, @selector(associatedObject),);
}
@end
小结
- 使用关联,我们可以不用修改类的定义而为其增加存储空间,在对于无法访问到类的源码的时候非常有用
- 关联是通过关键字来进行操作的,因而可以为任何对象增加任意多的关联,每个都使用不同的关键字即可
- 关联是可以保证被关联的对象在关联对象的整个生命周期都是可用的