美文网首页
OC类的加载-下

OC类的加载-下

作者: 浪的出名 | 来源:发表于2020-10-24 11:01 被阅读0次

    引言

    • 通过上文OC类的加载上知道加载类的时候会受到load方法的影响,加上分类的load方法,会出现下面四种情况
    • 1,非懒加载类和非懒加载分类
    • 2,懒加载类和非懒加载分类
    • 3,懒加载类和懒加载分类
    • 4,非懒加载类和懒加载分类

    分类的本质

    • 创建一个Person的分类Test,新增一个age属性,增加一个run方法,通过clang编译为cpp文件,可以看到分类的本质是一个结构体
    struct _category_t {
        const char *name;
        struct _class_t *cls;
        const struct _method_list_t *instance_methods;
        const struct _method_list_t *class_methods;
        const struct _protocol_list_t *protocols;
        const struct _prop_list_t *properties;
    };
    
    • 它里面有分类的名字,主类,实例方法列表,类方法列表,协议列表,属性列表,比较特殊的是它没有存储成员变量的数据,在分类中增加属性,只会生成一个set、get方法的声明
    • 查看方法列表,因为我在.m文件里实现了set、和get方法
    static struct /*_method_list_t*/ {
        unsigned int entsize;  // sizeof(struct _objc_method)
        unsigned int method_count;
        struct _objc_method method_list[3];
    } _OBJC_$_CATEGORY_INSTANCE_METHODS_Person_$_Test __attribute__ ((used, section ("__DATA,__objc_const"))) = {
        sizeof(_objc_method),
        3,
        {{(struct objc_selector *)"setAge:", "v20@0:8i16", (void *)_I_Person_Test_setAge_},
        {(struct objc_selector *)"age", "i16@0:8", (void *)_I_Person_Test_age},
        {(struct objc_selector *)"run", "v16@0:8", (void *)_I_Person_Test_run}}
    };
    
    • 我们也可以通过Developer Documentation搜索Category查看分类的结构
    • 还可以直接通过objc源码搜索category_t

    非懒加载类和非懒加载分类

    • 通过前面的分析,我们知道只要实现了load方法就可以让类或者分类变为非懒加载的类或者分类
    • 类的加载map_images->map_images_nolock->_read_images->_getObjc2NonlazyClassList->realizeClassWithoutSwift->methodizeClass->attachToClass->load_images
    • load_images里面开始加载分类,loadAllCategories->load_categories_nolock->attachCategories

    懒加载类和非懒加载分类

    • 我们实现了两个分类,在Test分类里面没有实现load,另外一个分类没有实现load
    • 类的加载load_images->prepare_load_methods->realizeClassWithoutSwift->methodizeClass->attachToClass通过断点调试发现,没有实现load方法的分类会通过直接读取Mach-O的数据到data(),然后在attachToClass里面实现了attachCategories加载分类的方法。

    懒加载类和懒加载分类

    • 类的加载会在第一次给类发送信息的时候,lookUpImpOrForward->initializeAndLeaveLocked->initializeAndMaybeRelock->realizeClassMaybeSwiftAndUnlock->realizeClassWithoutSwift->methodizeClass->attachToClass
    • 分类的数据在编译的时期就加入到Mach-O文件中。

    非懒加载类和懒加载分类

    • 类的加载map_images->map_images_nolock->_read_images->_getObjc2NonlazyClassList->realizeClassWithoutSwift->methodizeClass->attachToClass->load_images
    • 分类的数据在编译的时期就加入到Mach-O文件中。

    相关文章

      网友评论

          本文标题:OC类的加载-下

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