此文主要从Main函数之后分析;最后会从启动时间优化上分析main函数前后
1、App启动入口Main
在创建一个新项目时,可以在supporting Files中找到Main文件,其中只有一个main函数,程序的入口就是这个main函数。
2、UIApplicationMain的作用
This function is called in the main entry point to create the application object and the application delegate and set up the event cycle.
If the application’s Info.plist file specifies a main nib file to be loaded, by including the NSMainNibFile key and a valid nib file name for the value, this function loads that nib file.
以上是UIApplicationMain函数的描述(按住option + 左键可以查看)
翻译过来意思就是这个方法 创建了一个application对象和application delegate ,然后开启了事件循环
如果info.plist文件中有 NSMainNibFile的key值所对应的value ,加载这个nib文件
1、创建了Application对象
在main函数中,我们可以看到第三个参数为nil
系统默认为nil,系统也就默认创建了一个application 对象,我们可以通过[UIApplication sharedApplication]; 来获取。 如果我们想要系统创建一个我们自定义的UIApplication对象,那么就可以这么做:
如图1.2 ,我们自定义一个继承于UIApplication的类, NSStringFromClass([XHApplication class])作为参数,我们来看一下程序运行后的打印结果
此时,我们就可以通过[UIApplication sharedApplication]来获取到自定义的这个UIApplication对象了
2、创建了Application delegate 对象
Application delegate对象也是系统帮我们创建好的,默认为Appdelegate,通过UIApplicationMain函数中的参数可以看到他也是将类名传给函数了,那么同样的,我们也可以自定义一个自己的Appdelegate,需要遵循<UIApplicationDelegate>协议,同样通过NSStringFromClass将自己的Appdelegate对象 作为UIApplication对象的对象 (好绕口,不过很好理解)
小总结:Main函数创建了一个UIApplication对象(可以理解为我们的应用程序),创建了一个delegate对象,此对象作为UIApplication对象的代理,由此对象,我们可以获取程序的状态(加载完成、进入前台、进入后台等)
3、开启了运行循环
这里的运行循环指的就是runloop了。关于runloop的文章,相信大家看了很多了,简单一句话:runloop就是一个循环,没有任务时,程序休眠,有任务时,执行任务。后面我会更新一篇关于runloop底层的剖析(其实我现在还没看) 这里就不多说了
4、判断info.plist文件中是否有主窗口的nib文件
根据官方文档上的翻译:
如果info.plist文件中有 NSMainNibFile的key值所对应的value ,加载这个nib文件
如果info.plist文件中没有,那么创建主视图的任务应该在Appdelegate中的代理回调 didFinishLaunchingWithOptions 中处理
3、App启动优化
时间分为两个部分 T1(main之前) T2(main)
T1:系统环境布局时间:创建进程,加载解析可执行文件(库加载,堆栈环境配置等等)
T2:从main到第一个界面显示时间
1、库加载越多,启动越慢
2、Objc类越多,启动越慢
3、静态对象全局对象越多,启动越慢,原因是静态对象和全局对象是在编译时加载
4、Objc的 + load 方法越多,启动越慢,原因是load方法是在编译时运行
其中:第4点和T2时间上的优化更容易把控.
第一次写。后续会继续更新文章
若有不对之处,还请指出。