随着iOS项目愈来愈大,启动时间也会变得愈来愈慢,咱们如何来对app的启动时间来进行优化,给用户一个更好的体验呢?xcode
应用启动分为冷启动和热启动安全
- 冷启动是指内存中不存在与应用相关的数据,须要从硬盘时将应用的数据载入到内存中;这个过程是由系统决定的,平时咱们把应用杀死,而后立刻启动,此时内存中的应用相关的数据不会立刻被清除,因此这时候的启动不是冷启动;
- 热启动是指内存中还存留着应用相关的数据,应用运行所须要的数据不须要所有从硬盘中载入内存。
咱们能够经过设置环境变量来起到监控应用启动时间的目的,有关环境变量的设置,请参考Xcode环境变量markdown
咱们设置环境变量DYLD_PRINT_STATISTICS
,运行工程,打印应用启动时的时间消耗状况: 多线程
打印出应用启动时间以下: app
咱们以main函数为分隔点,将应该启动时间优化分为main函数以前和main函数以后,这里所打印的pre-main time就是main函数以前的耗时。函数
dylib loading time
:动态库的载入耗时,苹果建议项目中自定义的动态库最好不要超过6个动态库,若是超过了6个要考虑动态库合并;rebase/binding time
:偏移修正
(rebase)和符号绑定
(binding)的耗时;偏移修正是一个安全机制--ASLR
,原理是生成一个随机值,加到应用内存地址的前面,来起到方法、函数的地址随机的目的,解决安全问题.全部的方法、函数和数据的内存地址都会在原有的真实地址上加上这个随机值
,而且每次启动的时候这个随机值是不一样的,这样别人就无法拿到方法、函数或数据的真实地址了;符号绑定是指将方法名与方法的实现,即sel和IMP的绑定。ObjC setup time
:Object-C类的注册的耗时;不权威统计,每增长20000个类,这个时间增长800ms;减小类的数量能够减小启动耗时;initializer time
:load方法和构造方法的耗时.因此项目中要尽可能减小重写load 方法,将load方法的操做放在initialization中.
以上就是main函数以前的启动耗时说明及相关优化方案;post
对于main函数以后的启动耗时,咱们能够经过代码的方式进行监控,好比,在main函数中记录一个时间,到第一个界面显示的viewDidLoad方法中记录一个时间,两个时间的差值就是main函数以后的启动耗时.因为main函数以后的耗时须要根据不一样的项目来区分,不能一律而论,这里提供几个优化的建议优化
- 减小数据的加载,最好使用懒加载,如一个第三文库的加载;
- 将项目中再也不使用的类和方法去掉;
- 使用多线程技术加载数据,充分利用cpu的资源;
- 启动时刻的界面,不要使用storyboard或xib,尽可能使用纯代码,由于storyboard或xib有一步代码转换的操做,也是会耗时的。
应用程序在运行时,使用的是虚拟内存与物理内存相结合的方法加载数据的;虚拟内存是分页管理的,当使用到某一页虚拟内存的数据时,须要将对应的真实数据加载到物理内存中,将虚拟内存与物理内存以前造成一个映射关系,这个操做称为缺页异常(page fault),这个操做是需耗时的。spa
查看iOS应用的载入数据的顺序,咱们能够经过设置Write Link Map File
为yes,来查看应用数据加载的顺序 线程
clean
一下工程,而后command+B
编绎一下工程,来到Products的xx.app
目录下
再来到以下目录下
找到以下文件
打开此文件Demo-LinkMap-normal-x86_64.txt
这里的顺序就是应用数据加载的顺序,这里的顺序是由下以两个因素决定的
按文件顺序从上到下
按文件中的方法的顺序从上到下
验证一下此文件的顺序就是实际的载入顺序,能够经过修改文件或方法的顺序,而后从新编绎后查看link map文件的方法顺序是否改变。
因为咱们在应用在启动时可能只须要某些文件中的某些方法,而按照实际的方法载入顺序,在应用启动时会由于page fault
的存在,就须要载入大量的用不到的数据,形成了大量的时间消耗,为此咱们只须要在应用启动时只载入启动时须要的方法就能够了,其实的数据能够后续载入;为此咱们能够经过建立一个.order
文件来修改方法或函数的加载顺序.
打开hank.order
文件,查看如下几个方法的顺序
将此文件配置到对应的xcode工程中
clean后从新编绎,查看Demo-LinkMap-normal-x86_64
文件
这样咱们就成功的修改了方法或函数的加载顺序,因此咱们只须要知道应用启动时执行了哪些方法,将他们排序好,放在.order文件中,就能够在应用启动时,只加载了本身须要的数据,减小了page fault的次数,从而减小了启动耗时。
那么如何知道应用启动时执行了哪些方法呢?请看Hook一切的终极武器--Clang插桩