iOS runtime 关联对象

作者: LoveY34 | 来源:发表于2016-12-05 17:31 被阅读318次

    最近在看runtime的相关知识,感觉里面东西还蛮多的,反正感觉runtime被戴上了很多高大上的帽子。查看了很多文章,下面两个头文件是被提及的最多的,上面一个头文件主要提及到OC中的类、方法、属性和成员变量,详细的说明了他们的本质,而下面的头文件说明了OC中方法调用的本质,同时这些头文件中涉及到很多C语言中的概念,主要是结构体,结构体指针等,看着有点晕乎。

    #import <objc/runtime.h>
    #import <objc/message.h>
    

    但是我写这篇文章的主要意图是为了给runtime的关联对象做一个总结,当然现在也只是初步了解,后期有新的看法就会更新这篇文章的。

    1.关联对象的概念

    关联对象说的简单点就是利用键值对的方式把两个对象关联起来,而关联的唯一标示就是key值

    2.关联对象常用的方法
        /**
         *  @author liyong
         *
         *  为object添加关联对象value
         *
         *  @param object 关联对象中的被关联的对象
         *  @param key    关联的key值(这个key值必须保证是一个对象级别的唯一常量😂这地方有待研究,一个key值不知道为啥这么复杂)
         *  @param value  关联的对象
         *  @param policy 关联的内存管理策略
         *
         *  @return
         */
        objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
    
    • 关联的key值有三种推荐值
      1.声明 static char kAssociatedObjectKey; ,使用 &kAssociatedObjectKey 作为 key 值
      2.声明 static void *kAssociatedObjectKey = &kAssociatedObjectKey; ,使用 kAssociatedObjectKey 作为 key 值
      3.用 selector ,使用 getter 方法的名称作为 key 值(这种方法用的比较多)

    • policy是关联的对象的内存管理策略,是一个枚举类型,值有如下五种,使用方法跟属性的描述一样

    OBJC_ASSOCIATION_ASSIGN             // 对关联对象进行弱引用
    OBJC_ASSOCIATION_RETAIN_NONATOMIC   // 对关联对象进行强引用(非原子)
    OBJC_ASSOCIATION_COPY_NONATOMIC     // 对关联对象进行拷贝引用(非原子)
    OBJC_ASSOCIATION_RETAIN             // 对关联对象进行强引用
    OBJC_ASSOCIATION_COPY               // 对关联对象进行拷贝引用
    
        /**
         *  @author liyong
         *
         *  根据被关联的对象和关联的key值获取关联的对象
         *
         *  @param object 关联对象中的被关联的对象
         *  @param key    关联的key值
         *
         *  @return 关联的对象
         */
        objc_getAssociatedObject(id object, const void *key)
    
        /**
         *  @author liyong
         *
         *  移除被关联对象的所有关联对象
         *  但是这个方法用的不多,把objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
         *  中的value设为nil就会根据key清空object关联的对象
         */
        objc_removeAssociatedObjects(id object)
    

    大家要是觉得注释的不是很好的话,<objc/runtime.h>中有详细的英文注释。

    3.关联对象的用法

    关联对象用的最多的就是为已有的类添加属性(关于属性和实例变量的区别可以查看属性与实例变量),至于别的用法我暂时还没遇到😂😂(我感觉runtime在开发中用的本来就少,但是对runtime的学习有助于对OC和iOS开发的深入了解)。
    话不多说,直接上代码

    @interface LYPersonModel (testCategory)
    
    @property (copy, nonatomic) NSString *englishName;
    
    @end
    
    @implementation LYPersonModel (testCategory)
    
    - (void)setEnglishName:(NSString *)englishName
    {
        objc_setAssociatedObject(self, @selector(englishName), englishName, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    
    - (NSString *)englishName
    {
        return objc_getAssociatedObject(self, @selector(englishName));
    }
    
    @end
    

    代码不多,就两句,利用class_copyPropertyList()获取对象的成员变量就会发现类别中的属性也会出现列表中(但是利用class_copyIvarList()获取成员变量列表的时候发现没有待下划线的成员变量,看来关联对象只是变相的为类扩展了属性,实际上并没有扩张成员变量)。

    相关文章

      网友评论

        本文标题:iOS runtime 关联对象

        本文链接:https://www.haomeiwen.com/subject/lxokmttx.html