首页 > 代码库 > Objective-C中的关联(objc_setAssociatedObject,objc_getAssociatedObject,objc_removeAssociatedObjects)

Objective-C中的关联(objc_setAssociatedObject,objc_getAssociatedObject,objc_removeAssociatedObjects)

关联的概念

  所谓的关联,字面意思是把两个相关的对象放在一起,实际也是如此。把两个对象相互关联起来,使得其中的一个对象成为另外一个对象的一部分,这就是关联。

 

关联的作用

  使用Category,我们可以给一个类增加方法,而不用修改类文件本身。使用关联,我们就可以在类之外为类增加额外的存储空间,跟使用Category一样,不需要修改类文件本身。关联是基于关键字的,因此,我们可以为任何对象增加任意多的关联,每个关联都使用不同的关键字即可。关联是可以保证被关联的对象在关联对象的整个生命周期都是可用的(在垃圾自动回收环境下也不会导致资源不可回收)。

 

关联的创建

  创建关联需要使用Objc的运行时函数:objc_setAssociatedOjbect来把一个对象和另外一个对象进行关联,所以需要导入头文件<objc/runtime.h>。该函数需要四个参数:源对象、关键字、关联的对象、关联策略。

  关键字是一个void类型的指针。每一个关联的关键字必须是唯一的。通常都会采用静态变量来作为关键字。

  关联策略表明了相关的对象是通过赋值、保留引用还是赋值的方式来进行关联的;还有这种关联是原子的还是非原子的。这里的关联策略和声明属性时的很类似。这种关联策略是通过预先定义好的常量来表示的。

  下面的代码展示了如何把一个字符串关联到一个数组上。

    static char overViewKey;        NSArray * array = [@[@"One",@"Two",@"Three"] retain];    NSString * overView = [[NSString alloc] initWithFormat:@"First three number"];    objc_setAssociatedObject(array, &overViewKey, overView, OBJC_ASSOCIATION_RETAIN);        [overView release];//(1) overView仍然是可用的    [array release]; //(2) overView不可用

  在(1)处,字符串仍然是可用的,这是因为OBJC_ASSOCIATION_RETAIN策略指明了数组要持有相关的对象。当数组array被销毁的时候,也就是在(2)处,overView也就会被释放,因此而被销毁。如果此时还想使用overView,例如想通过NSLog来输出overView的值,则会出现异常。

 

获取相关的对象

  获取相关的对象时使用Objc的函数obc_getAssociatedObject。

    NSString * associatedOjbect = (NSString *)objc_getAssociatedObject(array, &overViewKey);

 

关联的断开

  断开关联时使用objc_setAssociatedOjbect,传入nil值即可。如:

objc_setAssociatedObject(array, &overViewKey, nil, OBJC_ASSOCIATION_ASSIGN);

  其中,被管理啊你的对象为nil,此时的关联策略也就无关紧要了。

  使用函数objc_removeAssociatedOjbects可以断开所有的关联。通常情况下不建议使用这个函数,因为它会断开所有的关联。只有在需要把对象回复到原始状态的时候才会使用这个函数。

 

一个完整的示例程序

#import <Foundation/Foundation.h>#import <objc/runtime.h>int main(int argc, const char * argv[]){    @autoreleasepool {                static char overviewKey;        NSArray * array = [@[@"One",@"Two",@"Three"] retain];        NSString * overview = [[NSString alloc] initWithString:@"First three nubmers"];        objc_setAssociatedObject(array, &overviewKey, overview, OBJC_ASSOCIATION_RETAIN);        [overview release];                NSString * associatedObject = (NSString *)objc_getAssociatedObject(array, &overviewKey);        NSLog(@"associatedObject:%@",associatedObject);                objc_setAssociatedObject(array, &overviewKey, nil, OBJC_ASSOCIATION_ASSIGN);                [array release];                    }    return 0;}

 

 

来自:http://blog.csdn.net/onlyou930/article/details/9299169,略有修改