美文网首页
Runtime底层Class是个什么?

Runtime底层Class是个什么?

作者: AntKing | 来源:发表于2019-04-09 22:45 被阅读0次

    Class

    • 在苹果开源的Runtime源码中可以找到这些数据结构
    
    //
    //  ysClassInfo.h
    //  TestClass
    //
    //  Created by ys Lee on 2018/3/8.
    //  Copyright © 2018年 ys Lee. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    #ifndef ysClassInfo_h
    #define ysClassInfo_h
    
    # if __arm64__
    #   define ISA_MASK        0x0000000ffffffff8ULL
    # elif __x86_64__
    #   define ISA_MASK        0x00007ffffffffff8ULL
    # endif
    
    #if __LP64__
    typedef uint32_t mask_t;
    #else
    typedef uint16_t mask_t;
    #endif
    typedef uintptr_t cache_key_t;
    
    struct bucket_t {
        cache_key_t _key;
        IMP _imp;
    };
    
    struct cache_t {
        bucket_t *_buckets;
        mask_t _mask;
        mask_t _occupied;
    };
    
    struct entsize_list_tt {
        uint32_t entsizeAndFlags;
        uint32_t count;
    };
    
    struct method_t {
        SEL name;
        const char *types;
        IMP imp;
    };
    
    struct method_list_t : entsize_list_tt {
        method_t first;
    };
    
    struct ivar_t {
        int32_t *offset;
        const char *name;
        const char *type;
        uint32_t alignment_raw;
        uint32_t size;
    };
    
    struct ivar_list_t : entsize_list_tt {
        ivar_t first;
    };
    
    struct property_t {
        const char *name;
        const char *attributes;
    };
    
    struct property_list_t : entsize_list_tt {
        property_t first;
    };
    
    struct chained_property_list {
        chained_property_list *next;
        uint32_t count;
        property_t list[0];
    };
    
    typedef uintptr_t protocol_ref_t;
    struct protocol_list_t {
        uintptr_t count;
        protocol_ref_t list[0];
    };
    
    struct class_ro_t {
        uint32_t flags;
        uint32_t instanceStart;
        uint32_t instanceSize;  // instance对象占用的内存空间
    #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;
    };
    
    struct class_rw_t {
        uint32_t flags;
        uint32_t version;
        const class_ro_t *ro;
        method_list_t * methods;    // 方法列表
        property_list_t *properties;    // 属性列表
        const protocol_list_t * protocols;  // 协议列表
        Class firstSubclass;
        Class nextSiblingClass;
        char *demangledName;
    };
    
    #define FAST_DATA_MASK          0x00007ffffffffff8UL
    struct class_data_bits_t {
        uintptr_t bits;
    public:
        class_rw_t* data() {
            return (class_rw_t *)(bits & FAST_DATA_MASK);
        }
    };
    
    /* OC对象 */
    struct objc_object {
        void *isa;
    };
    
    /* 类对象 */
    struct objc_class : objc_object {
        Class superclass;
        cache_t cache;
        class_data_bits_t bits;
    public:
        class_rw_t* data() {
            return bits.data();
        }
        
        objc_class* metaClass() {
            return (objc_class *)((long long)isa & ISA_MASK);
        }
    };
    
    #endif /* ysClassInfo_h */
    
    
    

    isa 指针具体指向哪里呢?

    • 下图总结的非常到位
    isa-superclass.png
    • 再来一张图解释清楚
    20190409224709.jpg

    方法调用轨迹

    instance的isa指向class

    class的isa指向meta-class

    meta-class的isa指向基类的meta-class

    class的superclass指向父类的class
    如果没有父类,superclass指针为nil

    meta-class的superclass指向父类的meta-class
    基类的meta-class的superclass指向基类的class

    instance调用对象方法的轨迹
    isa找到class,方法不存在,就通过superclass找父类

    class调用类方法的轨迹
    isa找meta-class,方法不存在,就通过superclass找父类

    相关文章

      网友评论

          本文标题:Runtime底层Class是个什么?

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