1. App启动过程
-
解析Info.plist
- 加载相关信息,例如如闪屏
- 沙箱建立、权限检查 -
Mach-O加载
- 如果是胖二进制文件,寻找合适当前CPU类别的部分
- 加载所有依赖的Mach-O文件(递归调用Mach-O加载的方法)
- 定位内部、外部指针引用,例如字符串、函数等
- 执行声明为attribute((constructor))的C函数
- 加载类扩展(Category)中的方法
- C++静态对象加载、调用ObjC的 +load 函数
-
程序执行
- 调用main()
- 调用UIApplicationMain()
- 调用applicationWillFinishLaunching
2. 如何测量启动过程耗时
冷启动比热启动重要
当用户按下home键的时候,iOS的App并不会马上被kill掉,还会继续存活若干时间。理想情况下,用户点击App的图标再次回来的时候,App几乎不需要做什么,就可以还原到退出前的状态,继续为用户服务。这种持续存活的情况下启动App,我们称为热启动,相对而言冷启动就是App被kill掉以后一切从头开始启动的过程。我们这里只讨论App冷启动的情况。
main()函数之前
在不越狱的情况下,以往很难精确的测量在main()函数之前的启动耗时,因而我们也往往容易忽略掉这部分数据。小型App确实不需要太过关注这部分。但如果是大型App(自定义的动态库超过50个、或编译结果二进制文件超过30MB),这部分耗时将会变得突出。所幸,苹果已经在Xcode中加入这部分的支持。
main()函数之后
从main()函数开始至applicationWillFinishLaunching结束,我们统一称为main()函数之后的部分。
3. 影响启动性能的因素
App启动过程中每一个步骤都会影响启动性能,但是有些部分所消耗的时间少之又少,另外有些部分根本无法避免,考虑到投入产出比,我们只列出我们可以优化的部分:
main()函数之前耗时的影响因素
- 动态库加载越多,启动越慢。
- ObjC类越多,启动越慢
- C的constructor函数越多,启动越慢
- C++静态对象越多,启动越慢
- ObjC的+load越多,启动越慢
main()函数之后耗时的影响因素
- 执行main()函数的耗时
- 执行applicationWillFinishLaunching的耗时
- rootViewController及其childViewController的加载、view及其subviews的加载
这些操作地方都是耗时影响主线程的问题,需要异步后台线程,处理然后主线程更新,展位图作占位。
网友评论