【iOS】关联属性存取数据

有时候我们需要在现有的类存放一些额外的信息,通常的做法是继承一个子类,然后定义新增加的属性,然而如果我们为每个需要的类都添加一个类显得太麻烦了,objc提供了一个关联属性的特性,可以给一个对象关联一个属性(做过.NET的朋友一定熟悉附加属性,objc的关联属性与.NET的附加属性有点类似类似)

使用关联属性很简单,下面是几个主要的函数

//设置关联属性
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)

//获取关联属性
id result = objc_getAssociatedObject(id object, const void *key)

//删除所有附加属性
objc_removeAssociatedObjects(id object)

我们声明属性的时候会声明:copy,retain,assign 内存管理方式,在设置关联属性的时候也有,即 objc_setAssociatedObject 的第四个参数

关联类型 等效@property属性

OBJC_ASSOCIATION_ASSIGN

assign

OBJC_ASSOCIATION_RETAIN_NONATOMIC

nonatomic, retain

OBJC_ASSOCIATION_COPY_NONATOMIC

nonatomic, copy

OBJC_ASSOCIATION_RETAIN

retain

OBJC_ASSOCIATION_COPY

copy

 

 

 

 

 

 

 

 

 

关联属性的附加相当于NSDictionary,通过键值对存储,但是有一点跟NSDictionary不一样的是,设置关联对象所用的键(key)是不透明指针(opaque pointer),NSDictionary判断两个Key的isEqual方法判断是否相等,而关联对象只判断两个key的地址是否相等,而不会比较对象具体的值

看看下面例子

    NSString *key1 = @"aaa";
    NSString *key2 = [NSString stringWithFormat:@"aaa"];
    NSString *key3 = @"bbb";
    
    NSObject *obj = [[NSObject alloc] init];
    
    objc_setAssociatedObject(obj, key1.UTF8String, @"aaa1", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    objc_setAssociatedObject(obj, key2.UTF8String, @"aaa2", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    objc_setAssociatedObject(obj, key3.UTF8String, @"bbb", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    id value1 = objc_getAssociatedObject(obj, key1.UTF8String);
    id value2 = objc_getAssociatedObject(obj, key2.UTF8String);
    id value3 = objc_getAssociatedObject(obj, key3.UTF8String);
    
    NSLog(@"value1 = %@", value1);
    NSLog(@"value2 = %@", value2);
    NSLog(@"value3 = %@", value3);

输出

  这里的key1和key2都是@"aaa",但是取出来的value1和value2却不一样,这是因为key1和key2的地址不一样,在匹配的时候关联对象视为不同的key,所以通常我们在定义关联对象的key的时候使用静态全局变量作为键,这样可以保证地址一致

    static char *key = "aaa";
    NSObject *obj = [[NSObject alloc] init];
    
    objc_setAssociatedObject(obj, key, @"aaa1", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    objc_setAssociatedObject(obj, key, @"aaa2", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    id value1 = objc_getAssociatedObject(obj, key);
    //把原有的值覆盖
    id value2 = objc_getAssociatedObject(obj, key);
    
    NSLog(@"value1 = %@", value1);
    NSLog(@"value2 = %@", value2);

 参考文章:

  《Effective Objective C 2.0》编写高质量iOS与OS X代码的52个有效方法 第10条

 

posted @ 2015-09-15 10:17 bomo 阅读(...) 评论(...) 编辑 收藏