使用dyld2启动应用的过程
1.加载dyld到App进程(dyld首先读取mach-o Header和load commands,接着就知道了这个可执行文件依赖的动态库)
2.加载动态库(包括所依赖的所有动态库)
3.Rebase & Bind (使用了ASLR地址空间布局随机化和Code Sign来保证应用的安全,Rebase修正内部指针指向,Bind修正外部指针指向)
4.初始化Objective-C Runtime (Runtime维护了一张映射类名与类的全局表,当加载一个dylib时,把类的信息注册到这个全局表中,也会把Category中的方法注册到对应的类中)
5.Initializers 其他初始化代码
6.dyld调用main()函数,main()函数调用UIApplicationMain(),程序启动。
dyld3加载方式
分析Mach-o Headers
分析依赖的动态库
查找需要Rebase & Bind之类的符号
把上述结果写入缓存
main函数之后:
(一)有storyboard
1.main函数
2.UIApplicationMain
创建UIApplication对象
创建UIApplication的delegate对象
3.根据Info.plist获得最主要storyboard的文件名,加载最主要的storyboard
创建UIWindow
创建和设置UIWindow的rootViewController
显示窗口
(二)没有storyboard
1.main函数
2.UIApplicationMain
创建UIApplication对象
创建UIApplication的delegate对象
3.delegate对象开始处理(监听)系统时间
程序启动完毕的时候, 就会调用代理的application:didFinishLaunchingWithOptions:方法
在application:didFinishLaunchingWithOptions:中创建UIWindow
创建和设置UIWindow的rootViewController
显示窗口
优化启动时间
main函数之后
能延迟执行的就延迟执行。比如SDK的初始化,界面的创建。
不能延迟执行的,尽量放到后台执行。比如数据读取,原始JSON数据转对象,日志发送。
main函数之前
减少动态库的数量
合并Category和功能类似的类。删除无用的方法和类。
用initialize替代load。