APP的启动分为两种
1.冷启动:从0开始启动
2.热启动:APP已存在内存中,在后台或者,再次点击图标
APP的启动时间的优化( 启动优化主要针对冷启动)
1.可以通过添加环境变量,打印出APP启动的时间分析(edit scheme ->run -> arguments)DYLD_PRINT_STATISTICS
APP冷启动的3个状态
1.dyld 2.runtime 3.main
App的启动优化
1.dyld
当点击APP的图标的时候,apple的动态连接器会去装在mach-o可执行文件 ( 编译项目,会生成APP包 target->prduct->***.app文件,.APP文件里面包含可执行文件,包含项目里面所有的代码,但是代码也会依赖很多的动态库,这些动态库不会包含在可执行文件中,可执行文件只包含引用信息,当加载执行文件的时候,系统会通过递归去查找所依赖的动态库。)
动态库与静态库的区别
静态库:在编译时会被完整地拷贝到可执行文件中,如果多次使用,就会有多次冗余拷贝。静态库的优势在于模块化,便于分工合作,避免少量改动导致的大量重复编译。通常以.a或.framework为后缀名。系统的.framework通常是动态库,而非系统的.framework通常是静态库
动态库:在编译时不复制,程序运行时由系统动态加载到内存,系统只加载一次,多个程序可以共用同一个库文件,节省内存。通常以.dylib(在iOS中通常为.framework)或.tbd为后缀名。
2.启动APP的时候runtime所做的事
1.调用map_images进行可执行文件内容的解析处理
2.在load_images中调用call_load_methods,调用所有的class和category的+load方法
3.进行各种objc结构的初始化(注册oc类,初始化类对象等)
4.调用c++静态初始化器和_attribute__((constructor))修饰的函数等
到此为止,可执行文件和动态库中的所有符号(class,protocol,selector,imp...)都成功按照格式加载到内存中,被runtime所管理
总结
1.app的启动事宜dyld为主导,将可执行文件中加载到内存中,顺便加载需要依赖的动态库
2.并由runtime负责加载成objc定义的结构
3.所有的工作完成后,dyld会调用main函数
4.接下来就是UIAppicationMain函数,appdelegate的didFinish函数
启动的优化
1.减少动态库的加载,及时清理用不到的动态库
2.减少分类的使用,及时清理不需要的分类和类
3.swift尽量使用结构体 不要使用类
4.尽量减少+load方法的使用,使用+initialize和dispathc_one来替代,(load与initialize的区别,load会在程序启动的时候调用,initialize只有当对该类发送消息的时候才会调用,load只会调用一次,initialize会调用多次)
5.在不影响用户体验的情况下,尽可能将一些操作延迟,不要都放在didFinish,按需加载