pre-main 及 +load方法

 pre-main

 静态库

 汇编生成的目标与引用的库一起打包到可执行文件生成最终的mach-o二进制可执行文件

 动态库

 程序编译的时候不会链接到动态库,程序运行才会链接, 动态库包括uikit, foundation,corefoundation, libdispatch,dyld等

 dyld会首先读取mach-o的header和loadcommonds,获取路径,加载相关依赖库,例如加载动态库A到内存,然后检查A所依赖的动态库

 (通常一个APP要加载的动态库100-400个),

 load_images方法主要做两件事, prepare_load_methods  call_load_methods, 在call_load_methods里先调用 class_loads,再调用 category_loads

 即先去除类,父类和分类的load方法, 第二步加载这些load方法, load方法在这里进行初始化


 +load方法应用场景 (hook方法 / 组件化开发, 不同组件之间的通信,在load方法中注册协议)

 1. +load是在类和分类在加载时调用的, 2. 只调用一次

 顺序是

 1. 类优先与分类调用

 2. 子类调用+load时,先调用父类的+load, ( 父类优先于子类, 与继承不同)

 3. 不同类按照编译顺序调用+load方法(先编译先调用)

 4, 分类也是按照编译顺序调用+load方法(先编译先调用)

prepare_loads


q

其中:

schedule_class_load(cls->superclass); //在调度类的load方法前,要先跳用父类的load方法(递归),决定了父类优先于子类调用

add_class_to_loadable_list(cls);  //添加到能够加载的类的列表中

当prepare_load_methods函数执行完之后,所有满足+load方法调用条件的类和分类就被分别保持在全局变量中; 等待执行


call_load_methods

当prepare_load_methods执行完,准备好类和分类后,就该调用他们的+load方法啦,在call_load_methods中进行调用;注意图中红色圈内部分,两个关键函数:call_class_loads(),call_category_loads() ;看到这两个函数想到了什么呢?

对,就是这两个函数决定了类优先与分类调用+load方法;

说明:+load方法是系统根据方法地址直接调用,并不是objc_msgSend函数调用(isa,superClass);这就决定了如果子类没有实现+load方法,那么当它被加载时runtime是不会调用父类的+load方法的,除非父类也实现了+load方法;

你可能感兴趣的:(pre-main 及 +load方法)