(看了戴铭老师的教程,做的笔记,做得不好,大家勿怪...)
要做iOS启动优化,就要先了解iOS启动的过程,iOS启动主要包括三个方面:
- main函数执行前
- main函数执行后(main函数开始执行->Appdelegate里面的首屏渲染结束)
- 首屏渲染之后
main函数执行之前,系统主要做了一下操作:
- App可执行文件的加载(.o文件的集合)
- 加载动态库(rebase指针的调整和bind符号的绑定)
- objc运行时的运行处理(objc相关类的注册,category注册,selector唯一性检查)
- 初始化(执行+load方法和attribute修饰的函数的调用,创建C++全局静态变量)
所以这个阶段可以做的启动速度优化包括:
- 减少动态库的加载,尽量合并多个动态库,保证最多使用不超过6个非系统动态库
- 减少加载不会使用的类或者方法
- 减少+load方法(可以使用+initialize替换)
- 控制C++全局变量的数量
main函数执行之后,系统主要做的操作有:
- 首屏初始化所需配置文件的读写操作
- 首屏列表大数据的读取
- 首屏渲染的大量计算等
所以这个阶段可以做的处理就是保证渲染的快速性,应该是梳理出哪些是首屏渲染必须做的初始化功能,哪些是只需要对应功能开始使用时才初始化的,然后进行处理,在合适的阶段进行运行;
首屏渲染之后
首屏渲染之后,主要需要我们处理的是非首屏其他业务服务模块的初始化、监听的注册、配置文件的读取等
检测App启动速度方法主要有两种:
-
使用Xcode中的Time Profiler定时抓取主线程上的方法调用堆栈,计算一段时间内的各个方法的耗时(照老师建议,时间间隔定为0.01为宜)
-
对objc_sendMsg进行hook来掌握所有方法的执行耗时;hook这种方式的优点是非常精确,而缺点是只能针对Objective-C的方法。
objc_msgSend 方法执行的逻辑是:先获取对象对应类的信息,再获取方法的缓存,根据方法的selector查找函数指针,经过异常错误处理后,最后跳到对应函数的实现。
有几个大佬的Demo可以参考一下:
刚刚看到一个CoderStar大佬的好文,也记录一下: