iOS学习iOS开发技术分享iOS Developer

优化应用的启动时间(实践篇)

2016-08-11  本文已影响627人  StanOz

上一篇笔记记录了 session 的理论部分,这里接着记录实践部分。

重述

简要地捋一下应用启动的过程:首先是 dyld 解析得到所需的共享库,然后将库映射到应用的地址空间里面,通过 rebasing 和 binding 修正函数和数据指针的地址,接着注册 ObjC 的类、调用所有的 initializers,最后才是调用 main() 函数。

测量

应用的启动的方式有两种——冷启动和热启动:前者是启动应用时没有任何数据被内核缓存,比如说重启设备后再打开应用就是冷启动;后者在启动时已经有数据被缓存,尽管你能退出这个应用,但是内核还是不一定会清除掉缓存。

要想测量调用 main() 函数之前的所耗费的时间,用我先前写的 TICK TOCK 这两个宏是不可能的。但是在 Xcode 中,可以添加一个环境变量 DYLD_PRINT_STATISTICS

DYLD_PRINT_STATISTICS.png

那么在启动的时候就能看动态库加载、rebase/binding 等等各部分的时间(Xcode 8,iOS 10 环境下):

pre_main_comsuming_hot.png pre_main_comsuming_cold.png

提升

Dylib Loading

Rebas/Binding

data_pointer.png

ObjC Setup

Initializers

Initializers 分为显式的和隐式的,这些都会在启动的时候被调用。我觉得这一块才是实际开发中值得注意的一部分:
对于显式的 initializers:

对于隐式的 initializers:

总结

在调用 main() 函数之前,我觉得能做的、对性能提升比较大的是在 initializers 这一块。类、实例变量等等的数目对启动的影响不大。而在进入 -application:didFinishLaunchingWithOptions: 之后,将一些不是必须在主线程进行的 IO 或计算任务放到低优先级的子线程中执行比较好,这样可以尽快的返回。

话说,site initializers 是什么意思啊,Google 了半天没找着……😢

上一篇 下一篇

猜你喜欢

热点阅读