zoukankan      html  css  js  c++  java
  • 【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条

  • 相关阅读:
    LeetCode 79. 单词搜索
    LeetCode 1143. 最长公共子序列
    LeetCode 55. 跳跃游戏
    LeetCode 48. 旋转图像
    LeetCode 93. 复原 IP 地址
    LeetCode 456. 132模式
    LeetCode 341. 扁平化嵌套列表迭代器
    LeetCode 73. 矩阵置零
    LeetCode 47. 全排列 II
    LeetCode 46. 全排列
  • 原文地址:https://www.cnblogs.com/bomo/p/4809457.html
Copyright © 2011-2022 走看看