美文网首页
iOS load方法

iOS load方法

作者: 学学学q | 来源:发表于2021-04-27 18:55 被阅读0次

    流程分析

    收到回调

        _dyld_objc_notify_register(&map_images, load_images, unmap_image);
    

    用到的数据结构:

    
    struct loadable_class {
        Class cls;  // may be nil
        IMP method;
    };
    
    
    // List of classes that need +load called (pending superclass +load)
    // This list always has superclasses first because of the way it is constructed
    static struct loadable_class *loadable_classes = nil;
    static int loadable_classes_used = 0;
    static int loadable_classes_allocated = 0;
    
    
    • 当自定义类,没有实现load方法,而只有它的分类实现,那么不会加入到_objc_catlist数据段中
    • 当自定义类和分类都实现了load方法,分类会加入到_objc_catlist数据段中

    read_image会将nlclslist里的类进行realizeClassWithoutSwift。这样如果一个自定义类,实现了load方法,在镜像映射完成的时候,也就被填充了内部信息。(只是类,不是分类这一步)
    load_image会首先加载共享缓存中的分类
    然后,准备那些实现了load方法的类prepare_load_methods

        void prepare_load_methods(const headerType *mhdr)
    {
        size_t count, i;
    
        runtimeLock.assertLocked();
    
        classref_t const *classlist = 
            _getObjc2NonlazyClassList(mhdr, &count);
        for (i = 0; i < count; i++) {
            schedule_class_load(remapClass(classlist[i]));
        }
    
        category_t * const *categorylist = _getObjc2NonlazyCategoryList(mhdr, &count);
        for (i = 0; i < count; i++) {
            category_t *cat = categorylist[i];
            Class cls = remapClass(cat->cls);
            if (!cls) continue;  // category for ignored weak-linked class
            if (cls->isSwiftStable()) {
                _objc_fatal("Swift class extensions and categories on Swift "
                            "classes are not allowed to have +load methods");
            }
            printf("------------%s\n", cat->name);
            realizeClassWithoutSwift(cls, nil);
            ASSERT(cls->ISA()->isRealized());
            add_category_to_loadable_list(cat);
        }
    }
        
    

    这里有一个关键的方法是schedule_class_load,它会先将父类的class的load方法加入loadable_classes

    static void schedule_class_load(Class cls)
    {
        if (!cls) return;
        ASSERT(cls->isRealized());  // _read_images should realize
    
        if (cls->data()->flags & RW_LOADED) return;
    
        // Ensure superclass-first ordering
        schedule_class_load(cls->getSuperclass());
    
        add_class_to_loadable_list(cls);
        cls->setInfo(RW_LOADED); 
    }
    

    schedule_class_load方法将有load方法的类加入loadable_classes

     category_t * const *categorylist = _getObjc2NonlazyCategoryList(mhdr, &count);
    

    这个方法获取__objc_catlist2数据段下的分类,通过add_category_to_loadable_list(cat);方法加入loadable_categories

    然后接下来通过call_load_methods()方法调用+load方法

    void call_load_methods(void)
    {
        static bool loading = NO;
        bool more_categories;
    
        loadMethodLock.assertLocked();
    
        // Re-entrant calls do nothing; the outermost call will finish the job.
        if (loading) return;
        loading = YES;
    
        void *pool = objc_autoreleasePoolPush();
    
        do {
            // 1. Repeatedly call class +loads until there aren't any more
            while (loadable_classes_used > 0) {
                call_class_loads();
            }
    
            // 2. Call category +loads ONCE
            more_categories = call_category_loads();
    
            // 3. Run more +loads if there are classes OR more untried categories
        } while (loadable_classes_used > 0  ||  more_categories);
    
        objc_autoreleasePoolPop(pool);
    
        loading = NO;
    }
    

    循环调用load方法,并调用分类的load方法

    realizeClassWithoutSwift学习

    realizeClassWithoutSwift这方法很重要,有空看

    /***********************************************************************
    * realizeClassWithoutSwift
    * Performs first-time initialization on class cls, 
    * including allocating its read-write data.
    * Does not perform any Swift-side initialization.
    * Returns the real class structure for the class. 
    * Locking: runtimeLock must be write-locked by the caller
    **********************************************************************/
    

    相关文章

      网友评论

          本文标题:iOS load方法

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