当App启动时,发生了什么(转自Medium)
你是否想过在按下app icon图标时到application::didFinishLaunchingWithOptions:?之间发生了什么
iPhone app技术上讲可以概括的描述为一个函数UIApplicationMain(::::)
下面一起探究以下其中原理
UIApplication
如果你研究UIApplicationMain(::::)这个方法,你会发现他的返回值是Int32类型.其实,这个方法从来不会真的退出,直到app退出,和你的app生命周期一致
第一件事,app调用一个类UIApplication这个类非常重要,是控制,协同app运行的关键
每个app只有一个该对象实例,是单例模式,UIApplication.shared就是这个单例对象
UIApplicationDelegate
另一件事,创建AppDelegate,是一个遵守UIApplicationDelegate协议的对象,你可能对它已经很熟悉了,处理app交互的根对象
UIApplicationDelegate有一堆方法,用来管理你的app
你是否注意到@UIApplicationMain标记在类声明之前?UIApplicationMain(::::)根据这个标记知道哪个类是Appdelegate.这个类也是和app的生命周期同步.也被指向为UIApplication的代理对象
应用对象遇到重要的runtime事件时,会通知AppDelegate,例如app运行,内存警告,app终止,给予响应的机会
在iOS13,上述的一些响应职责被SceneDelegate接手处理了.负责app生命周期的响应职责由appDelegate处理,一些和app显示,窗口交互的响应职责由sceneDelegate处理
Storyboard?
此时,app的基础功能已经就绪了,UIApplicationMain(::::)开始准备处理交互了
首先,需要找到main storyboard,这个行为是和Info.plist的key叫做”Main storyboard file base name”有关
如果使用storyboard绘制界面,app会实例化UIWindow,UIVindow是UIView的子类.这个实例化的window是你用户界面的基础
一旦实例化完成,window被赋值SceneDelegate的属性(在iOS13之前是AppDelegate的属性)
如果你观察SceneDelegate里的scene(_:willConnectTo:options:)方法,你能注意到瞎买你的注释:
If using a storyboard, the
window
property will automatically be initialized and attached to the scene.
现在开始window属性和app生命周期保持一致了
ViewController的初始化
用户虽然创建了UIWindow的实例,但是现在却看不到任何东西的,用户并不会直接和window交互,能看到的是window里的rootViewController属性
rootViewController包含着你的initial view controller,你可以通过storyboard指定initial view controller,在”Attributes inspector”,选中”Is initial view controller”
选中之后就被赋值给rootViewController属性,它是window现在唯一的直接的subview.其他的view都是rootview的subview
现在是时候调用application:didFinishLaunchingWithOptions:方法了
但window还是不可见,最一步需要调用makeKeyAndVisible()实例方法
此时app已经就绪,功能开始执行了
无No Storyboard
有些项目不使用storyboard,靠纯代码绘制界面,这种情况下,你必须要在UIApplicationMain里自己写相关代码
在iOS13之前,写上述代码的位置在didFinishLaunchingWithOptions,现在要写在SceneDelegate里的
(_willConnectTo:options:)方法里
你要写的代码内容:
- 实例化UIWindow,赋值给SceneDelegate
’s
window属性 - 实例化你的initial view controller并且赋值给window
的
rootViewController属性 - 调用makeKeyAndVisible()展示界面
代码:
1 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { |
总结
上述的过程都是不可见的,在app内部处理,很多人没有思考过其中的细节.是app生命周期重要的部分