根据以上两张图片来看,app的启动过程如下:
1、打开app,调用main函数
2、main调用UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]))
第三个参数nil:代表UIApplication类名或者子类名称,nil 相当于 @"UIApplicaiton"
;
第四个参数:代表UIApplicaiton的代理名称NSStringFromClass([AppDelegate class] 相当于 @"AppDelegate"
;
2.1、UIApplicationMain创建UIApplication对象,AppDelegate对象(UIApplication的代理)
2.2、UIApplication开启运行循环(Main Runloop)
注:UiApplication代表一个应用程序,每一个应用程序都有一个UIApplication全局对象(单例),我们在程序中可以通过[UIApplication sharedApplication]
获得这个对象,进行一些应用级的操作。UIApplication负责监听接收事件,而由UIApplicationDelegate决定应用程序如何去响应这些事件(生命周期:程序启动和关闭,系统事件:来电、记事项警告)等等。
2.3、加载info.plist,判断是否指定mian(xib或者storyboard)如果指定就去加载
3、UIApplicationDelegate对象开始处理监听到的事件(
程序启动成功之后,首先调用application:didFinishLaunchingWithOptions:方法,
如果info.plist文件中配置了启动storyboard文件名,则加载storyboard文件。
如果没有配置,则根据代码来创建UIWindow--->UIWindow的rootViewController-->显示)
info.plist文件:
Localiztion native development region | CFBundleDevelopmentRegion 本地化相关,如果用户所在地没有相应的语言资源,则用这个key的value来作为默认 |
Executaule file | CFBundleExecutable 程序安装包的名称 |
Bundle name | CFBundleDisplayName 设置程序安装后显示的名称。应用程序名称限制在10-12个字符,如果超出,将被显示缩写名称 |
Bundle identifier | CFBundleIdentifier APP的唯一标识字符串。 |
InfoDictionary version | CFBundleInfoDictionaryVersion Info.plist格式的版本信息 |
Bundle OS Type code | CFBundlePackageType 用来标识束类型的四个字母长的代码(目前没用到过,还不清楚怎么用) |
Bundle versions string, short | CFBundleShortVersionString 版本字符串(版本号) |
Bundle version | CFBundleVersion 构建版本号,每次上传之后需要增加 |
Application require iPhone environment | LSRequiresIPhoneOS:用于指示程序包是否只能运行在iPhone OS 系统上。Xcode自动加入这个键,并将它的值设置为true。您不应该改变这个键的值。 |
supported interface orientations | UISupportedInterfaceOrientations 程序默认支持的方向。 |
APP的状态:
Not running ( 未运行 ): 程序没启动。
Inactive ( 未激活 ): 程序在前台运行,不过没有接收到事件。在没有事件处理情况下程序通常停留在这个状态。
Active ( 激活 ): 程序在前台运行而且接收到了事件。这也是前台的一个正常的模式。
Backgroud ( 后台 ): 程序在后台而且能执行代码,大多数程序进入这个状态后会在在这个状态上停留一会。时间到之后会进入挂起状态(Suspended)。有的程序经过特殊的请求后可以长期处于Backgroud状态。
Suspended ( 挂起 ): 程序在后台但是却不能执行代码。系统会自动把程序变成这个状态而且不会发出通知。
当挂起时,程序还是停留在 内存中的,当系统内存低时,系统就把挂起的程序清除掉,为前台程序提供更多的内存。
APPdelegate中状态改变调用的方法:
// 程序 开始运行
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
return YES;
}
// 程序 挂起(有电话进来 或者 锁屏(拉下状态栏、双击Home键使App界面上移) 的时候)
- (void)applicationWillResignActive:(UIApplication *)application {
}
// 程序 进入后台
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
// 程序 进入前台
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
// 程序 重新激活(复原)注意:应用程序在启动时,在调用了“applicationDidFinishLaunching”方法之后 同样也会 调用“applicationDidBecomeActive”方法!
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
// 程序 终止(注:如果点击主按钮强制退出,则不会调用该方法。)
- (void)applicationWillTerminate:(UIApplication *)application {
}
实际使用中碰到的几个场景:
- “点击桌面图标,正常启动App” 或者 “杀死进程后点击推送消息,启动App” :
1.application:willFinishLaunchingWithOptions
2.application:application:didFinishLaunchingWithOptions
3.applicationDidBecomeActive
4.application:didRegisterForRemoteNotificationsWithDeviceToken // 接收、处理消息通知
- 拖下通知中心/双击Home键,使App界面上移 :
applicationWillResignActive
- 拖上通知中心/再双击Home键,使App界面恢复原位:
applicationDidBecomeActive
- 按Home键,使App 进入后台
1.applicationWillResignActive
2.applicationDidEnterBackground
- 点击App图标,使App从后台 恢复至前台
1.applicationWillEnterForeground
2.applicationDidBecomeActive
- 点击通知中心里面的远程推送,使App从后台 进入前台
1.applicationWillEnterForeground
2.application:didReceiveRemoteNotification // 接收、处理消息通知
3.applicationDidBecomeActive
- 上滑 或者 按住App图标,选择减号图标,杀死App进程(终止程序)
applicationWillTerminate
- 从APP切换到微信之类的其他应用之后,再切换回来时
1.applicationWillEnterForeground
2.application:openURL:sourceApplication // 应用间⭐️传值⭐️
3.applicationDidBecomeActive