- 当我们点击应用图标,操作系统会为我们分配一个进程
- 然后调用dyld(动态连接库) 接管后续的工作;
- 加载可执行文件
这一步dyld将二进制文件加载到运行内存,主要分三个步骤:- 检验二进制文件是否合法,是否符合当前cpu的架构,例如iOS系统是arm64/arm7,mac osx 是 i38u/x86_64
- 选择使用dyld加载可执行文件;
- 注册对应的镜像
- 链接过程主要分为两步:
- 首先递归加载程序依赖的动态链接库;
- 执行指针矫正:
注意: 在链接过程会进行指针矫正,原因因为可执行文件在进行内存分配的时候是随机布局分配,即ASLR问题,时机分配布局的地址与原来的地址分布有差异,所以要进行指针矫正;指针错乱主要分为两种: 1. 执行可执行文件的指针,对于此类指针的修复,调用rebaase函数进行修复, 2. 从当前可执行文件的发出指向其他镜像可执行文件的指针,调用bind函数进行修复;
- 在bind修复完指针指向的问题后,开始进行objc-setup阶段,也就是oc-runtime初始化阶段,这个阶段主要将class/protocol/selector/imp加载到内存;
- 完成oc-runtime阶段的初始化后,就可以对业务代码就行初始化,首先初始化业务代码依赖的第三方库或者sdk,然后初始化自己,完成后该可执行文件就可以调用main函数啦,到此也就完成了app启动的过程。
app启动优化:
- 我们可以借助以下instrument 的time_profile在检测程序的启动时间;一般400ms以内最佳;
优化的方向分两个阶段:
一、优化过程1: pre-main,即main函数执行之前,优化如下:
- 尽量删除一些不必要的系统文件和第三方库;
- 尽量删除一些不必要的.h .m 文件;
- 尽量不要在类的load函数放入大量初始化信息,这样会延迟加载时间;
二、 优化过程2: didfinishlauch函数到第一个主界面加载显示阶段,优化如下: - 减少不必要的网络请求
2.较少不必要的数据初始化操作,尽量写成懒加载 - 减少一些第三方sdk的初始化和版本检测相关代码