美文网首页IOS底层
iOS底层解析-----Cateogry解析 关联对象原理

iOS底层解析-----Cateogry解析 关联对象原理

作者: Mr丨Yang | 来源:发表于2019-03-05 11:27 被阅读42次

    先抛出 分类Category 的底层结构


    分类数据结构.png

    Category的用法经常用到,第一印象就是给一个类扩展方法
    本文主要分析一下三个问题
    1.分类的方法的运行原理以及它方法的运行顺序
    2.从分类角度深入分析load initialize 方法的调用原理及调用顺序
    3.关联属性的实现原理

    1.分类的方法的运行原理以及它方法的运行顺序
    isa指针看继承关系中我们知道一个实例对象的方法存放在它的class对象中,那么我们给一个类添加的Cateogry方法是否也存放在它的类的class对象中
    先看代码

    @interface Person : NSObject
    - (void)run;
    @end
    
    @implementation Person
    - (void)run
    {
        NSLog(@"Person - run");
    }
    @end
    
    
    @interface Person (Test) 
    - (void)test;
    @end
    
    @implementation Person (Test)
    - (void)test
    {
        NSLog(@"test");
    }
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            Person *person = [[Person alloc] init];
            [person run];
            [person test];
        }
        return 0;
    }
    
    [person run] 与 [person test] 都运行了,看编译后的代码如下: 编译后数据结构.png 它的数据结构就是如开始的数据结构表,这个数据表在运行时的时候会动态的添加到Person实例类的Class类中,动态添加过程如下: category的加载处理过程.png

    那么有上面的解释可看出,一个类的分类方法会优先类的方法调用,因为它在class类的方法数据结构的前面,所以会优先调用,那么可以解释如下代码

    @interface Person : NSObject
    - (void)run;
    @end
    
    @implementation Person
    - (void)run
    {
        NSLog(@"Person - run");
    }
    @end
    
    
    @interface Person (Test) 
    - (void)test;
    @end
    
    @implementation Person (Test)
    - (void)run
    {
        NSLog(@"Person(test) - run");
    }
    - (void)test
    {
        NSLog(@"test");
    }
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            Person *person = [[Person alloc] init];
      
            [person run];//会调用分类中的run方法
        }
        return 0;
    }
    

    2.从分类角度深入分析load initialize 方法的调用原理及调用顺序
    只给出结论,不再展开分析

    +load方法 +load方法.png +initialize方法 +initialize方法.png

    3.关联属性的实现原理

    默认情况下,因为分类底层结构的限制,不能添加成员变量到分类中,但是可以通过关联对象来间接实现
    
    关联对象提供了以下API
    //添加关联对象
    void objc_setAssociatedObject(id object, const void *key, id value,objc_AssociationPolicy policy)
    
    //获取关联对象
    id objc_getAssociatedObject(id object, const void *key)
    
    //移除所有的关联对象
    void objc_removeAssociatedObjects(id object)
    
    
    key的最优用法
    objc_setAssociatedObject(obj, @selector(getter),  value, OHJC_ASS0CIATION_RETAIN_NONATOMIC)
    
    objc_getAssociatedObject(obj, @selector(getter))
    
    
    修饰符.png

    实现原理(hashMap)


    核心对象.png 实现过程 过程.png

    下篇笔记链接
    iOS 底层解析-----Block (上)

    相关文章

      网友评论

        本文标题:iOS底层解析-----Cateogry解析 关联对象原理

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