关联
关联是指把两个对象相互关联起来,使得其中的一个对象作为另外一个对象的一部分
有时候需要在对象中存放相关信息。这时候我们通常会考虑从对象所属的类中继承一个子类。但是有时候类的实例可能是由某种机制所创,开发者无法令这种机制创建出自己所写的子类实例。Objective-C提供了一个钟强大的特性来解决这个问题,就是“关联对象”
使用关联,我们可以不用修改类的定义而为其对象增加存储空间。这在我们无法访问到类的源码的时候或者是考虑到二进制兼容性的时候是非常有用。
关联是基于关键字的,因此,我们可以为任何对象增加任意多的关联,每个都使用不同的关键字即可。关联是可以保证被关联的对象在关联对象的整个生命周期都是可用的(在垃圾自动回收环境下也不会导致资源不可回收)。
创建关联对象涉及到几个方法:
void objc_setAssociatedObject(id object,void *key,id value,objc_AssociationPolicy policy)
以给定的键和策略为某个对象设置关联对象值。
id objc_getAssociatedObject(id object,void *key)
根据给定的键从某个对象中获取相应的关联对象值
void objc_removeAssociatedObjects(id object)
移除指定对象的全部关联对象(使用这个函数,会断开所有关联,使对象回到初始状态)
在这里分析一下每个参数的含义:
1、id object 源对象,即宿主
2、void *key 关键字,一个void类型的指针。每一个关联的关键字必须是唯一的。通常都是会采用静态变量来作为关键字,我们可以通过这个关键字设置源对象的关联对象,也可以从源对象获取关联对象。此关键字就相当于字典中的key,但是两者有一个重要的差别:设置关联对象是用的key是一个“不透明的指针”。如果在两个键上调用“isEqual”方法的返回值是YES,那么NSDictionary就认为二者相等,然而在设置关联对象的值是,若想令两个键匹配到同一个值,则二者必须是完全相同的指针,所以在设置关联对象值时,通常使用静态全局变量做键。
3、id value 关联对象,即寄生对象
4、objc_AssociationPolicy policy 关联策略,关联策略表明了相关的对象是通过赋值,保留引用还是复制的方式进行关联的;还有这种关联是原子的还是非原子的。这里的关联策略和声明属性时的很类似。
关联类型 | 等效的@property属性 |
---|---|
OBJC_ASSOCIATIOB_ASSIGN | assign |
OBJC_ASSOCIATIOB_RETAIN_NONATOMIC | nonatomic,retain |
OBJC_ASSOCIATIOB_COPY_NONATOMIC | nonatomic,copy |
OBJC_ASSOCIATIOB_RETAIN | retain |
OBJC_ASSOCIATIOB_COPY | copy |
实例: 将一个数组关联到一个字符串上
static char key;
NSArray *array = [NSArray arrayWithObjects:@1,@2,@3,@4,nil];
NSString *str = [NSString stringWithFormat:@"%@",@"1234"];
//设置关联
objc_setAssociatedObject(str,&key,array,OBJC_ASSOCIATIOB_COPY_NONATOMIC);
//读取
NSArray *getArray = objc_getAssociatedObject(str,&key);
NSLog("%@",getArray);
//输出 1,2,3,4
//取消关联
objc_removeAssociatedObjects(str);
//或者重新设置相应key的关联对象为nil (推荐使用)
//objc_setAssociatedObject(str,&key,nil,OBJC_ASSOCIATIOB_COPY_NONATOMIC);