美文网首页
iOS runtime详细内容

iOS runtime详细内容

作者: XieHenry | 来源:发表于2021-04-14 22:52 被阅读0次
    runtime的主要数据结构.png

    一. objc_object结构体 objc_class结构体

    1.1 objc_object结构体
    image.png image1.png
    • isa指针分为 指针型isa非指针型isa
    image.png
    1.2 objc_class结构体
    结构体主要内容:
    struct objc_class : objc_object {
        // Class ISA;
        Class superclass;
        cache_t cache;             // formerly cache pointer and vtable
        class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
    
        class_rw_t *data() { 
            return bits.data();
        }
        ......
    }
    
    image.png
    1.3 cache_t结构体
    struct cache_t {
        struct bucket_t *_buckets;//可以理解为一个数组
        mask_t _mask;
        mask_t _occupied;
        ......
    }
    
    方法缓存的数据结构.png 通过哈希查找.png image.png

    cache_t的特点:
    1.用于快速查找方法执行函数
    2.是可增量扩展哈希表结构(增量拓展:结构的量增大,内存也会增大)
    3.是局部性原理的最佳应用(局部性原理:调用次数较高的方法)

    1.4 class_data_bits_t结构体

    class_data_bits_t包含class_rw_t,class_rw_t内包含

    struct class_rw_t {
        uint32_t flags;
        uint32_t version;
    
        const class_ro_t *ro;
    
        method_array_t methods;
        property_array_t properties;
        protocol_array_t protocols;
    
        Class firstSubclass;
        Class nextSiblingClass;
    
        char *demangledName;
        ......
    }
    
    struct class_ro_t {
        uint32_t flags;
        uint32_t instanceStart;
        uint32_t instanceSize;
    #ifdef __LP64__
        uint32_t reserved;
    #endif
    
        const uint8_t * ivarLayout;
        
        const char * name;
        method_list_t * baseMethodList;
        protocol_list_t * baseProtocols;
        const ivar_list_t * ivars;
    
        const uint8_t * weakIvarLayout;
        property_list_t *baseProperties;
    
        method_list_t *baseMethods() const {
            return baseMethodList;
        }
    };
    
    image.png
    • 一个类定义的变量 方法 属性都在class_data_bits_t这个成员结构内
    image.png

    protocols(协议) properties(属性) methods(方法) 是一个二维数组,还包括一些分类等

    image.png

    name 类名
    ivars 声明,定义的成员变量
    properties 属性
    protocols 协议
    methods 方法
    他们是一个一维数组

    image.png image.png

    二.类对象 元类对象

    类对象 存储实例方法列表等信息
    元类对象 存储类方法列表等信息

    image.png

    问题1:类对象和元类对象之间有什么区别和联系?

    实例对象通过isa指针找到类对象
    类对象当中存储方法列表等信息
    类对象通过isa指针找到元类对象、从而可以访问类方法列表等相关信息
    类对象和元类对象都是objc_class数据结构,因为继承objc_object。所以他们才有isa指针,进而可以实现实例对象通过isa指针找到类对象,进而可以访问实例方法列表等信息。类对象通过isa指针找到元类对象、从而可以访问类方法列表的相关信息。

    问题2:如果我们调用的类方法,没有对应的实现。但是有同名的实例方法,会不会发生崩溃,会不会产生实际的调用?

    由于根元类对象的superclass指针,指向了根类对象,当我们在元类对象当中查找类方法列表查不到的时候。会顺着指针去实例方法列表查找。如果有同名方法,就会调用同名方法的实例方法调用。

    问题3:实例方法的传递过程?

    系统根据当前的isa指针。找到它的类对象,在它的类对象当中查找方法列表。没有查找到的话,就会根据superclass查找父类的类对象的方法列表。然后根类对象的方法列表,如果还没有,就进入消息转发流程。

    问题4:类方法的传递过程?

    通过类对象的isa指针,找到元类对象。在它的元类对象当中查找方法列表。没有查找到的话,就会根据superclass查找父类的元类对象的方法列表。然后顺次遍历方法列表,直到根元类对象,再到根类对象。然后根类对象的方法列表,如果还没有,就进入消息转发流程。

    问题4:类对象 元类对象isa指向问题。

    元类对象的isa指针 指向 根元类对象
    根元类对象isa指针 指向 根元类对象
    根元类对象的superclass指针指向根类对象

    问题5:打印结果

    image.png

    结果都是Phone。因为接收者都是当前对象。


    image.png

    问题6:消息传递的机制?
    首先通过 哈希查找 查找缓存,缓存没命中,查当前类的方法列表是否命中(对于已排序好的列表,采用二分查找,对于没有排序的列表,采用一般遍历查找方法)。如果仍然没命中,逐级父类方法列表是否命中(父类查找是先通过superclass指针查找父类,遍历每一个父类,对于每一个父类,又通过缓存查找和当前类方法列表查找)。如果都没有命中,进入消息转发流程。

    image.png

    问题7:[obj foo]和objc_msgSend()函数之间有什么关系?
    编译之后,会在内部变成objc_msgSend()函数调用。

    问题8:消息转发流程3个步骤
    1.resolvelnstanceMethod(告诉系统是否要解决当前的方法实现)
    2.forwardingTargetForSelector:(告诉系统这个实例方法的调用应该由哪个对象来处理,转发对象是谁)
    3.methodSignatureForSelector:(1.返回方法签名,调用forwardInvocation,如果可以处理,转发结束 2.如果返回为nil,或者forwardInvocation无法处理,无法找到方法崩溃)

    image.png

    问题9:runtime如何通过Selector找到对应的IMP地址的?
    首先查找当前实例对应类对象的缓存是否有Selector对应的IMP实现,如果缓存命中,就把命中的缓存函数返回给调用方。如果缓存没有命中。根据当前类的方法列表查找Selector对应的IMP事件。当前类如果没有命中,再根据当前类的superClass指针逐级查找父类的方法列表。然后查找Selector对应的IMP事件。

    问题10:@dynamic (动态方法解析)
    相当于在运行时添加set get方法。而不是在编译时声明好

    动态运行时语言将函数决议推迟到运行时
    编译时语言在编译期进行函数决议

    相关文章

      网友评论

          本文标题:iOS runtime详细内容

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