• load


    load方法什么时候调用?

    method Swizzling 为什么要放在load方法里面?

     

    /***********************************************************************

    * _objc_init

    * Bootstrap initialization. Registers our image notifier with dyld.

    * Called by libSystem BEFORE library initialization time

    **********************************************************************/

     

    void _objc_init(void)

    {

        static bool initialized = false;

        if (initialized) return;

        initialized = true;

        

        // fixme defer initialization until an objc-using image is found?

        environ_init();

        tls_init();

        static_init();

        lock_init();

        exception_init();

     

        _dyld_objc_notify_register(&map_images, load_images, unmap_image);

    }

     

    进入load_images方法

    void

    load_images(const char *path __unused, const struct mach_header *mh)

    {

        // Return without taking locks if there are no +load methods here.

        if (!hasLoadMethods((const headerType *)mh)) return;

     

        recursive_mutex_locker_t lock(loadMethodLock);

     

        // Discover load methods

        {

            mutex_locker_t lock2(runtimeLock);

            prepare_load_methods((const headerType *)mh);

        }

     

        // Call +load methods (without runtimeLock - re-entrant)

        call_load_methods();

    }

     

    prepare_load_methods 准备load方法

    call_load_methods(); 所以load的方法是在所有loadImages之后,map映射到内存中之后调用的,在start函数之前

    其中prepare_load_methods方法:

    类的方法,分类,父类的load方法调用顺序?

    load如何加载?

    load如何调用? 

    void prepare_load_methods(const headerType *mhdr)

    {

        size_t count, i;

     

        runtimeLock.assertLocked();

     

        classref_t *classlist = 

            _getObjc2NonlazyClassList(mhdr, &count);

        for (i = 0; i < count; i++) {

            schedule_class_load(remapClass(classlist[i]));

        }

     

        category_t **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

            realizeClass(cls);

            assert(cls->ISA()->isRealized());

            add_category_to_loadable_list(cat);

        }

    }

     

     

    /***********************************************************************

    * call_load_methods

    * Call all pending class and category +load methods.

    * Class +load methods are called superclass-first. 

    * Category +load methods are not called until after the parent class's +load.

    * 

    * This method must be RE-ENTRANT, because a +load could trigger 

    * more image mapping. In addition, the superclass-first ordering 

    * must be preserved in the face of re-entrant calls. Therefore, 

    * only the OUTERMOST call of this function will do anything, and 

    * that call will handle all loadable classes, even those generated 

    * while it was running.

    *

    * The sequence below preserves +load ordering in the face of 

    * image loading during a +load, and make sure that no 

    * +load method is forgotten because it was added during 

    * a +load call.

    * Sequence:

    * 1. Repeatedly call class +loads until there aren't any more

    * 2. Call category +loads ONCE.

    * 3. Run more +loads if:

    *    (a) there are more classes to load, OR

    *    (b) there are some potential category +loads that have 

    *        still never been attempted.

    * Category +loads are only run once to ensure "parent class first" 

    * ordering, even if a category +load triggers a new loadable class 

    * and a new loadable category attached to that class. 

    *

    * Locking: loadMethodLock must be held by the caller 

      All other locks must not be held.

    **********************************************************************/

    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;

    }

     

    /***********************************************************************

    * call_class_loads

    * Call all pending class +load methods.

    * If new classes become loadable, +load is NOT called for them.

    *

    * Called only by call_load_methods().

    **********************************************************************/

    static void call_class_loads(void)

    {

        int i;

        

        // Detach current loadable list.

        struct loadable_class *classes = loadable_classes;

        int used = loadable_classes_used;

        loadable_classes = nil;

        loadable_classes_allocated = 0;

        loadable_classes_used = 0;

        

        // Call all +loads for the detached list.

        for (i = 0; i < used; i++) {

            Class cls = classes[i].cls;

            load_method_t load_method = (load_method_t)classes[i].method;

            if (!cls) continue; 

     

            if (PrintLoading) {

                _objc_inform("LOAD: +[%s load] ", cls->nameForLogging());

            }

            (*load_method)(cls, SEL_load);

        }

        

        // Destroy the detached list.

        if (classes) free(classes);

    }

     

     

  • 相关阅读:
    我觉得 一个 单片机 代码 程序猿 连一个链表都不会写的 话 ,太说不过去了 ,学习 一下
    peripheralStateNotificationCB
    SimpleProfile_GetParameter && SimpleProfile_SetParameter
    performPeriodicTask
    如何在IAR工程中创建和使用模板
    英语 单词 收集
    KD-树(下)
    KD-树(上)
    KNN
    命令方式联网与界面network-manager方式联网
  • 原文地址:https://www.cnblogs.com/coolcold/p/12056909.html
Copyright © 2020-2023  润新知