笔记01

作者: fearless123 | 来源:发表于2020-04-14 09:59 被阅读0次

    1、objc_object、objc_class、class_rw_t、class_ro_t、cache_t、bucket_t、method_t、protocol_t、ivar_t、property_t

    • objc_class 结构体继承自objc_object
    struct objc_object {
        Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
    };
    
    struct objc_class : objc_object {
        // Class ISA;
        Class superclass;          // objc_class类型的指针,指向父类的objc_class结构体
        cache_t cache;             // 方法缓存,可增量扩展的哈希表
        class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
    }
    
    // 用散列表缓存调用过的方法,提高方法查询速度
    struct cache_t {
        struct bucket_t *_buckets; // 可变长度的结构体数组
        mask_t _mask;  //  散列表长度 - 1
        mask_t _occupied; // 已经缓存的方法数量(散列表形式存在,会空槽)
    }
    
    typedef uintptr_t cache_key_t;
    using MethodCacheIMP = IMP;
    struct bucket_t {
        MethodCacheIMP _imp; // IMP
        cache_key_t _key;  // SEL 
    }
    
    class_rw_t = class_data_bits_t & FAST_DATA_MASK;
    struct class_rw_t {
        const class_ro_t *ro;         // 编译时就确定好的
        method_array_t methods;       // 方法列表 二维数组
        property_array_t properties;  // 属性列表 二维数组
        protocol_array_t protocols;   // 协议列表 二维数组
        char *demangledName;          // 类名
    }
    
    struct class_ro_t {
        uint32_t instanceSize;            // 长度
        const char * name;                // 类名
        method_list_t * baseMethodList;   // 方法列表 一维数组
        protocol_list_t * baseProtocols;  // 协议 一维数组
        const ivar_list_t * ivars;        // 成员变量 一维数组
        property_list_t *baseProperties;  // 属性 一维数组
    };
    
    struct method_t {
        SEL name;          // 方法名
        const char *types; // 函数参数 + 返回值类型  
        MethodListIMP imp; // 方法地址
    }
    
    struct protocol_t : objc_object {
        const char *mangledName;                // 协议名
        struct protocol_list_t *protocols;      // 协议列表
        method_list_t *instanceMethods;         // 实例方法
        method_list_t *classMethods;            // 类方法
        method_list_t *optionalInstanceMethods; // 可选实例方法
        method_list_t *optionalClassMethods;    // 可选类方法
        property_list_t *instanceProperties;    // 实例属性
        property_list_t *_classProperties;      // 类属性
        const char *demangledName();
    }
    
    struct ivar_t {
        int32_t *offset;    // 地址中的偏移
        const char *name;   // 变量名
        const char *type;   // 变量类型
    };
    
    struct property_t {
        const char *name;       // 属性名
        const char *attributes; // 属性内容:strong、weak...
    };
    
    • 编译后class_data_bits_t 指向的是一个class_ro_t的地址(只读),运行时,通过realizeClass()函数将bits指向class_rw_t
    • 初始化类:realizeClass -> 设置rwro
    // 初始化类信息
    static Class realizeClass(Class cls) {
        const class_ro_t *ro;
        class_rw_t *rw;
        Class supercls;
        Class metacls;
        bool isMeta; 
    
        // 是否为空
        if (!cls) return nil;
        // 是否已经初始化
        if (cls->isRealized()) return cls;
        assert(cls == remapClass(cls));
    
        // 取出class中的data
        ro = (const class_ro_t *)cls->data();
        if (ro->flags & RO_FUTURE) {
            // class初始化
            rw = cls->data();
            ro = cls->data()->ro;
            cls->changeInfo(RW_REALIZED|RW_REALIZING, RW_FUTURE);
        } else {
            // 创建class_rw_t
            rw = (class_rw_t *)calloc(sizeof(class_rw_t), 1);
            // 给class_rw_t里面的class_ro_t赋值
            rw->ro = ro;
            // 设置状态
            rw->flags = RW_REALIZED|RW_REALIZING;
            // 给cls->data重新赋值class_rw_t
            cls->setData(rw);
        }
    
        isMeta = ro->flags & RO_META;
        rw->version = isMeta ? 7 : 0;  // old runtime went up to 6
    
        supercls = realizeClass(remapClass(cls->superclass));
        metacls = realizeClass(remapClass(cls->ISA()));
    
        cls->superclass = supercls;
        cls->initClassIsa(metacls);
        cls->setInstanceSize(ro->instanceSize);
    
        if (supercls) {
            addSubclass(supercls, cls);
        } else {
            addRootClass(cls);
        }
    
        // 取出class_ro_t中的数据,赋值给class_rw_t
        methodizeClass(cls);
        return cls;
    }
    
    
    • 初始化类后,class_rw_t中的methods、protocols、properties的都是空的,需要在methodizeClass函数中进行赋值,将class_ro_t中的数据取出,赋值给class_rw_t
    // 给rw赋值method list、protocol list、property list
    static void methodizeClass(Class cls) {
        bool isMeta = cls->isMetaClass();
        auto rw = cls->data();
        auto ro = rw->ro;
    
        // Install methods and properties that the class implements itself.
        // 1、把ro中的方法添加到rw中
        method_list_t *list = ro->baseMethods();
        if (list) {
            prepareMethodLists(cls, &list, 1, YES, isBundleClass(cls));
            rw->methods.attachLists(&list, 1);
        }
    
        // 2、把ro中的属性添加到rw中
        property_list_t *proplist = ro->baseProperties;
        if (proplist) {
            rw->properties.attachLists(&proplist, 1);
        }
        
        // 3、把ro中的协议添加到rw中
        protocol_list_t *protolist = ro->baseProtocols;
        if (protolist) {
            rw->protocols.attachLists(&protolist, 1);
        }
    
        if (cls->isRootMetaclass()) {
            addMethod(cls, SEL_initialize, (IMP)&objc_noop_imp, "", NO);
        }
    
        // Attach categories.
        // 把分类中的方法、属性、协议添加到类中去
        category_list *cats = unattachedCategoriesForClass(cls, true /*realizing*/);
        attachCategories(cls, cats, false /*don't flush caches*/);
    
        if (cats) free(cats);
    }
    
    

    相关文章

      网友评论

          本文标题:笔记01

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