美文网首页
2019-09-21load 理解

2019-09-21load 理解

作者: 胡志强 | 来源:发表于2019-09-28 18:17 被阅读0次

load runtime加载类或者分类时候调用
load 的调用原理通过查看源码

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);
}

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();
}
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;
}
加载类的
struct loadable_class {
    Class cls;  // may be nil
    IMP method; 只有load方法
};
加载分类的
struct loadable_category {
    Category cat;  // may be nil
    IMP method; 只有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
        if (cls->isSwiftStable()) {
            _objc_fatal("Swift class extensions and categories on Swift "
                        "classes are not allowed to have +load methods");
        }
        realizeClassWithoutSwift(cls);
        assert(cls->ISA()->isRealized());
        add_category_to_loadable_list(cat);
    }
}
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->superclass);
    //将cls添加到loadable_list数组后面
    add_class_to_loadable_list(cls);
    cls->setInfo(RW_LOADED); 
}
void add_category_to_loadable_list(Category cat)
{
    IMP method;

    loadMethodLock.assertLocked();

    method = _category_getLoadMethod(cat);

    // Don't bother if cat has no +load method
    if (!method) return;

    if (PrintLoading) {
        _objc_inform("LOAD: category '%s(%s)' scheduled for +load", 
                     _category_getClassName(cat), _category_getName(cat));
    }
    
    if (loadable_categories_used == loadable_categories_allocated) {
        loadable_categories_allocated = loadable_categories_allocated*2 + 16;
        loadable_categories = (struct loadable_category *)
            realloc(loadable_categories,
                              loadable_categories_allocated *
                              sizeof(struct loadable_category));
    }

    loadable_categories[loadable_categories_used].cat = cat;
    loadable_categories[loadable_categories_used].method = method;
    loadable_categories_used++;
}

相关文章

  • 2019-09-21load 理解

    load runtime加载类或者分类时候调用load 的调用原理通过查看源码 load调用顺序

  • 理解!理解!!理解!!!

    1、如何理解MVC设计模式 MVC是一种架构模式,M表示MOdel,V表示视图View,C表示控制器Control...

  • 理解“理解”

    教育不是灌输而是揭示 教育就是向智者揭示智慧,对愚者掩盖无知。——安布罗斯 比尔斯 我们的课堂教学要做的是设计表现...

  • 理解理解,再理解

    【今日悦读】 1214-潇潇 书名:财富自由之路 作者:李笑来 篇目:10~12节 收获: 1,人生三大坑 莫名其...

  • 理解不被理解

    一个人的坐在电脑前发呆,不知道搞什么,闭上眼睛,感觉自己很孤独。这种是内心的那种,很不是滋味,不知道什么时候自己才...

  • 理解你的理解理顺理解

    理解你的理解理顺你的理解 生活中因为缺乏准确具体到位的沟通和具体的实施方向和可落地的方式,因为信息传达...

  • 理解不理解

    对于更多人而言,或许他们更看重的是对与错,是与非。这种执念而且经常让一些人变了味,甚至格格不入。 而对于个人而言,...

  • 理解不曾理解的

    上学时从来没把容貌当成大事儿,只是希望脸上的痘痘能少点,至于什么皮肤白、毛孔粗大、黑眼圈、肤色暗淡、脸型、眉形、眼...

  • 理解与被理解

    凡事都设身处地为别人着想,自己不愿做的事情也不强加给别人,理解的核心在于不自我。

  • 理解什么是理解

    《理解什么是理解》-花花 每个人都渴望被理解,希望被理解,不被理解是一件很痛苦的事情。 小朋友不理解妈妈为对自己反...

网友评论

      本文标题:2019-09-21load 理解

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