+load方法

网上有很多这样的面试题,之前也有人问过我。但是一直也没有时间进行详细的探索,并做记录。

最近正好拿出来进行研究。下面会用到源码objc4-781,在官网上下载最新的。

我们先来看一下+load方法,我们新建几个类和分类,类和分类里面写上+load方法,并做打印

main函数里面什么也不写,头文件也不需要引入,我们运行一下,看一下会有什么效果。

运行之后的结果

我们可以看到这里已经调用了上面定义的类和分类的+load方法,我们什么都没有做,为什么会调用呢?

我们想要分析为什么,还需要从源码进行分析。

首先我们要找到runtime的入口,入口是在objc-os.mm文件下面的_objc_init方法


_objc_init方法

_dyld_objc_notify_register里面load_images点进去之后下面有个 call_load_methods()方法点进去

call_load_methods()

上面是先调用类方法里面的+load方法,下面是调用分类里面的+load方法。从上面的打印结果我们也可以看出是先调用类的在调用分类的。看一下调用方法里面的实现。


call_class_loads()

loadable_classes是非懒加载类+load 方法的数组。是loadable_class结构体,里面包含Class和IMP两个变量。所以classes里面也是同样的,之后用for循环遍历直接调用load方法。

但是loadable_classes数组里面的东西还有一些细节需要注意。就是里面存储结构体的顺序什么样的。因为顺序不同调用的结果也就不一样。到底在哪里看呢?

上面我们有一个load_images方法,里面有一句prepare_load_methods((const headerType *)mh);代码,点进去

prepare_load_methods

我们可以看到classlist里面放的是所有不是懒加载的类,通过for循环调用schedule_class_load这个方法。

schedule_class_load

add_class_to_loadable_list这个方法里面就是把有+load的发放入到loadable_classes数组中。但是上面可以看出使用了递归,

是对传入进来类的父类进行遍历。所以加入loadable_classes数组放把父类的+load方法先放到里面。所以在下面调用的时候是先调用父类的+load。

除了继承关系以外,其他的顺序是按照编译的顺序进行调用。

分类原理类似,但是不会像类一样先调用父类的load,分类只是单纯的按照编译顺序进行调用。

prepare_load_methods

这里也可以看出直接就调用添加数组里面。

总结一下+load方法

1、+load方法会在runtime加载类和分类时调用

2、调用的顺序有几个注意点(先调用类的load方法,如果类有继承关系先调用父类的load方法---类才有的,分类没有,其他情况就是按照编译的顺序进行调用,先编译先调用)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 精华总结:Category中有load方法, load方法会在runtime加载类的时候调用 类的load方法调用...
    二斤寂寞阅读 2,154评论 0 3
  • Objective-C之Category的底层实现原理Objective-C的+initialize方法调用原理分...
    RUNNING_NIUER阅读 2,009评论 0 13
  • +load方法会在程序初始化时候调用 每个类和分类的+load方法都会调用,并且只调用一次 调用顺序1. 先调用类...
    Nomo_C阅读 660评论 0 0
  • 原文在我的blog objc.com +load方法简介 +load方法在这个类的文件被程序装载时调用。只要是在C...
    字节码阅读 1,000评论 0 0
  • 一、调用规则 1、一个类的load方法在所有父类load方法调用之后调用 2、分类的load方法在当前类的load...
    Code_人生阅读 211评论 0 0