iOS main之前发生了什么

粗分两部分: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中的方法尽可能少

参考博客:

左神的博客:https://github.com/draveness/analyze/blob/master/contents/objc/%E6%B7%B1%E5%85%A5%E8%A7%A3%E6%9E%90%20ObjC%20%E4%B8%AD%E6%96%B9%E6%B3%95%E7%9A%84%E7%BB%93%E6%9E%84.md

http://blog.sunnyxx.com/2014/08/30/objc-pre-main/

http://yulingtianxia.com/blog/2016/10/30/Optimizing-App-Startup-Time/

猜你喜欢

转载自blog.csdn.net/ivolcano/article/details/89739531