关联对象 AssociatedObject 完全解析

  • 关联对象 AssociatedObject 完全解析
    • 关联
      • category与associative作为objective-c的扩展机制的两个特性
        • ✓ category即类型,可以通过它来扩展方法
        • ✓ associative,可以通过它来扩展属性
        • ✓ 在iOS开发中,可能category比较常见,相对的associative,就用的比较少,要用它必须使用的头文件,然后就可以*使用objc_getAssociatedObject以及objc_setAssociatedObject
      • ✓ 关联是指把两个对象相互关联起来,使得其中的一个对象作为另外一个对象的一部分。
      • ✓ 使用关联,我们可以不用修改类的定义而为其对象增加存储空间。这在我们无法访问到类的源码的时候或者是考虑到二进制兼容性的时候是非常有用。
      • ✓ 关联是基于关键字的,因此,我们可以为任何对象增加任意多的关联,每个都使用不同的关键字即可。关联是可以保证被关联的对象在关联对象的整个生命周期都是可用的(在垃圾自动回收环境下也不会导致资源不可回收)。
      • ✓ 引用:我们在 iOS 开发中经常需要使用分类(Category),为已经存在的类添加属性的需求,但是使用 @property 并不能在分类中正确创建实例变量和存取方法。
      •  
      • 不过,通过 Objective-C 运行时中的关联对象,也就是 Associated Object,我们可以实现上述需求。
      •  
      • 作者:Draveness
      • 链接:https://www.jianshu.com/p/79479a09a8c0
      • 来源:简书
    • Q:我们为什么要使用关联对象?
      • A:因为在分类中 @property 并不会自动生成实例变量以及存取方法,所以一般使用关联对象为已经存在的类添加『属性』。
        •  #import "DKObject+Category.h"
          #import <objc/runtime.h>
          
          @implementation DKObject (Category)
          
          - (NSString *)categoryProperty {
              return objc_getAssociatedObject(self, _cmd);
          }
          
          - (void)setCategoryProperty:(NSString *)categoryProperty {
              objc_setAssociatedObject(self, @selector(categoryProperty), categoryProperty, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
          }
          
          @end

           

        • ✓ 这里的 _cmd 代指当前方法的选择子,也就是 @selector(categoryProperty)。
        • ✓ 我们使用了两个方法 objc_getAssociatedObject 以及 objc_setAssociatedObject 来模拟『属性』的存取方法,而使用关联对象模拟实例变量。
        • 1.为什么向方法中传入 @selector(categoryProperty)?
        • 2.OBJC_ASSOCIATION_RETAIN_NONATOMIC 是干什么的?
          • ✓ id objc_getAssociatedObject(id object, const void *key);
          • void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
          • ✓ @selector(categoryProperty) 也就是参数中的 key,其实可以使用静态指针 static void * 类型的参数来代替,不过在这里,笔者强烈推荐使用 @selector(categoryProperty) 作为 key 传入。因为这种方法省略了声明参数的代码,并且能很好地保证 key 的唯一性。
          • OBJC_ASSOCIATION_RETAIN_NONATOMIC 又是什么呢?如果我们使用 Command 加左键查看它的定义:
            • typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
                  OBJC_ASSOCIATION_ASSIGN = 0,           /**< Specifies a weak reference to the associated object. */
                  OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object. 
                                                          *   The association is not made atomically. */
                  OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   /**< Specifies that the associated object is copied. 
                                                          *   The association is not made atomically. */
                  OBJC_ASSOCIATION_RETAIN = 01401,       /**< Specifies a strong reference to the associated object.
                                                          *   The association is made atomically. */
                  OBJC_ASSOCIATION_COPY = 01403          /**< Specifies that the associated object is copied.
                                                          *   The association is made atomically. */
              };

               

            • ✓ 从这里的注释我们能看到很多东西,也就是说不同的 objc_AssociationPolicy 对应了不通的属性修饰符:
      • @property` 其实有元编程的思想,它能够为我们自动生成实例变量以及存取方法,而这三者构成了属性这个类似于语法糖的概念,为我们提供了更便利的点语法来访问属性:
        • ✓ 在分类中,因为类的实例变量的布局已经固定,使用 @property 已经无法向固定的布局中添加新的实例变量(这样做可能会覆盖子类的实例变量),所以我们需要使用关联对象以及两个方法来模拟构成属性的三个要素。
        • 作者:Draveness
        • 链接:https://www.jianshu.com/p/79479a09a8c0
上一篇:objc_msgSend 作用


下一篇:lsscsi命令详解