一. iOS程序的启动执行顺序
程序启动顺序图
具体执行流程
-
程序入口
进入
main
函数,设置
AppDelegate
称为函数的代理 -
main函数中执行了一个UIApplicationMain这个函数.
1
2
3
4
5
6
7
8
int
main(
int
argc,
char
* argv[])
{
@autoreleasepool {
return
UIApplicationMain(argc, argv, nil, NSStringFromClass([JNAppDelegate
class
]));
}
}
int
UIApplicationMain(
int
argc,
char
*argv[], NSString *principalClassName, NSString *delegateClassName)
delegateClassName:指定应用程序的代理类,该类必须遵守UIApplicationDelegate协议.
UIApplicationMain函数会根据principalClassName创建UIApplication对象,根据delegateClassName创建一个delegate对象,并将该delegate对象赋值给UIApplication对象中的delegate属性.
接着会建立应用程序的Main Runloop(事件循环),进行事件的处理(首先会在程序启动完毕后调用delegate对象的application:didFinishLaunchingWithOptions:方法)
程序正常退出时UIApplicationMain函数才返回.
-
程序完成加载
[AppDelegate application:didFinishLaunchingWithOptions:]
-
创建
window
窗口 -
程序被激活
[AppDelegate applicationDidBecomeActive:]
-
当点击
command+H
时(针对模拟器,手机是当点击
home键
)
程序取消激活状态
[AppDelegate applicationWillResignActive:];
程序进入后台
[AppDelegate applicationDidEnterBackground:];
-
点击进入工程
程序进入前台
[AppDelegate applicationWillEnterForeground:]
程序被激活
[AppDelegate applicationDidBecomeActive:];
分析
1. 对于
applicationWillResignActive(非活动)
与
applicationDidEnterBackground(后台)
这两个的区别
-
applicationWillResignActive(非活动)
:
比如当有电话进来或短信进来或锁屏等情况下,这时应用程序挂起进入非活动状态,也就是手机界面还是显示着你当前的应用程序的窗口,只不过被别的任务强制占用了,也可能是即将进入后台状态(因为要先进入非活动状态然后进入后台状态) -
applicationDidEnterBackground(后台)
:
指当前窗口不是你的App,大多数程序进入这个后台会在这个状态上停留一会,时间到之后会进入
挂起状态(Suspended)
。如果你程序特殊处理后可以长期处于后台状态也可以运行。
Suspended (挂起)
: 程序在后台不能执行代码。系统会自动把程序变成这个状态而且不会发出通知。当挂起时,程序还是停留在内存中的,当系统内存低时,系统就把挂起的程序清除掉,为前台程序提供更多的内存。
如下图所示:
2.
UIApplicationMain
函数解释:
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);
-
argc
和
argv
参数是为了与C语言保持一致。 -
principalClassName (主要类名)
和 **
delegateClassName (委托类名)
**。
(1) 如果
principalClassName
是nil,那么它的值将从
Info.plist
去获取,如果
Info.plist
没有,则默认为
UIApplication
。
principalClass
这个类除了管理整个程序的生命周期之外什么都不做,它只负责监听事件然后交给
delegateClass
去做。
(2)
delegateClass
将在工程新建时实例化一个对象。
NSStringFromClass([AppDelegate class])
-
AppDelegate
类实现文件
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(@"--- %s ---",__func__);//__func__打印方法名
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
NSLog(@"--- %s ---",__func__);
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@"--- %s ---",__func__);
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(@"--- %s ---",__func__);
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(@"--- %s ---",__func__);
}
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
NSLog(@"--- %s ---",__func__);
}
- (void)applicationWillTerminate:(UIApplication *)application {
NSLog(@"--- %s ---",__func__);
}
打印调用顺序
启动程序
--- -[AppDelegate application:didFinishLaunchingWithOptions:] ---
--- -[AppDelegate applicationDidBecomeActive:] ---
按下
Command + H + SHIFT
--- -[AppDelegate applicationWillResignActive:] ---
--- -[AppDelegate applicationDidEnterBackground:] ---
重新点击 进入程序
--- -[AppDelegate applicationWillEnterForeground:] ---
--- -[AppDelegate applicationDidBecomeActive:] ---
选择 模拟器的
Simulate Memory Warning
--- -[AppDelegate applicationDidReceiveMemoryWarning:] ---
分析:
1.
application:didFinishLaunchingWithOptions
:
程序首次已经完成启动时执行,一般在这个函数里创建window对象,将程序内容通过window呈现给用户。
-
applicationWillResignActive(非活动)
程序将要失去
Active
状态时调用,比如有
电话
进来或者按下
Home键
,之后程序进入后台状态,对应的
applicationWillEnterForeground(即将进入前台)
方法。
该函数里面主要执行操作:
a . 暂停正在执行的任务
b. 禁止计时器
c. 减少
OpenGL ES
帧率
d. 若为游戏应暂停游戏
3.
applicationDidEnterBackground(已经进入后台)
对应
applicationDidBecomeActive(已经变成前台)
该方法用来:
a. 释放共享资源
b. 保存用户数据(写到硬盘)
c. 作废计时器
d. 保存足够的程序状态以便下次修复;
-
applicationWillEnterForeground(即将进入前台)
程序即将进入前台时调用,对应
applicationWillResignActive(即将进入后台)
,
这个方法用来: 撤销
applicationWillResignActive
中做的改变。 -
applicationDidBecomeActive(已经进入前台)
程序已经变为
Active(前台)
时调用。对应
applicationDidEnterBackground(已经进入后台)
。
注意: 若程序之前在后台,在此方法内刷新用户界面 -
applicationWillTerminate
程序即将退出时调用。记得保存数据,如
applicationDidEnterBackground
方法一样。