粗分两部分:dyld与runtime
细分主要包括四大部分:
1)加载可执行文件(Mach-O文件:二进制文件)
2)加载动态库()
3)Objc初始化,入口_obj_init(Objc相关类的注册,Category分类,selector唯一性检查等)
4)初始化加载进内存,如load方法
过程:
Load dylibs ----> Rebase ----> Bind ---->Objc ----> initializer
为什么要rebase,rebind?
Objc初始化讲解:
加载可执行文件和动态链接库后,dyld开始对这些二进制文件进行初始化,调用map_images做解析和处理,这里进行第一次初始化realizeClass,作用为类提前分配好内存,即类的一些方法、属性和协议是在编译期就决定的。接下来load_image中调用call_load_methods方法,遍历所有加载进来的class,按继承层次依次调用class,也就是父类的load方法比子类加载内存的时机要早,然后再处理分类,分类的load方法单独加入分类列表。
至此,可执行文件中和动态库所有的符号(Class,Protocol,Selector,IMP,…)都已经按格式成功加载到内存中,被 runtime 所管理,再这之后,runtime 的那些方法(动态添加 Class、swizzle 等等才能生效)
具体的:
Parse Image
Map Image
Rebase Image
Bind Image
Run image initializer
Call Main
Call UIApplicationMain
Call applicationWillFinishLaunching:
总结:
提高启动速度的几个方法:
1.减少动态库的加载数量
2.减少无用类
3.load中的方法尽可能少
参考博客:
http://blog.sunnyxx.com/2014/08/30/objc-pre-main/
http://yulingtianxia.com/blog/2016/10/30/Optimizing-App-Startup-Time/