标签:
对于iOS应用程序,关键是要知道你的应用程序是否正在前台或后台运行。由于系统资源在iOS设备上较为有限,一个应用程序必须在后台与前台有 不同的行为。操作系统也会限制你的应用程序在后台的运行,以提高电池寿命,并提高用户与前台应用程序的体验。当应用程序在前台和后台之间切换时,操作系统 将会通知您的应用程序。你可以通过这些通知来修改你的应用程序的行为。
当你的应用程序在前台活动时,系统会发送触摸事件给它进行处理。在UIKit的基础设施做了大部分的事件传递给你的自定义对象工作。所以您需要 做的是覆盖在相应的对象的方法来处理这些事件。对于控件,UIKit会通过处理你的触摸事件,或者其他一些有趣的事情发生时调用您的自定义代码,比如 当文本字段中的值更改。
1、应用程序的状态
Not running 未运行:程序没启动。
Inactive 未激活:程序在前台运行,不过没有接收到事件。在没有事件处理情况下程序通常停留在这个状态。
Active 激活:程序在前台运行而且接收到了事件。这也是前台的一个正常的模式。
Backgroud 后台:程序在后台而且能执行代码,大多数程序进入这个状态后会在在这个状态上停留一会。时间到之后会进入挂起状态(Suspended)。有的程序经过特殊的请求后可以长期处于Backgroud状态。
Suspended 挂起:程序在后台不能执行代码。系统会自动把程序变成这个状态而且不会发出通知。当挂起时,程序还是停留在内存中的,当系统内存低时,系统就把挂起的程序清除掉,为前台程序提供更多的内存。
2、各个程序运行状态时代理的回调
①告诉代理进程启动但还没进入状态保存
- - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- NSLog(@"①告诉代理进程启动但还没进入状态保存");
- return YES;
- }
②告诉代理启动基本完成程序准备开始运行
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
-
- NSLog(@"②告诉代理启动基本完成程序准备开始运行");
-
-
-
- self.window.backgroundColor = [UIColor whiteColor];
- [self.window makeKeyAndVisible];
- return YES;
- }
③当应用程序将要入非活动状态执行,在此期间,应用程序不接收消息或事件,比如来电话
- - (void)applicationWillResignActive:(UIApplication *)application
- {
-
-
- NSLog(@"③当应用程序将要入非活动状态执行,在此期间,应用程序不接收消息或事件,比如来电话");
- }
④当应用程序进入活动状态执行
- - (void)applicationDidBecomeActive:(UIApplication *)application
- {
-
- NSLog(@"④当应用程序进入活动状态执行");
- }
⑤当程序被推送到后台的时候调用。所以要设置后台继续运行,则在这个函数里面设置即可
- - (void)applicationDidEnterBackground:(UIApplication *)application
- {
-
-
- NSLog(@"⑤当程序被推送到后台的时候调用");
-
- [application beginBackgroundTaskWithExpirationHandler:^{
-
- NSLog(@"begin Background Task With Expiration Handler");
-
- }];
- }
⑥当程序从后台将要重新回到前台时候调用
- - (void)applicationWillEnterForeground:(UIApplication *)application
- {
-
- NSLog(@"⑥当程序从后台将要重新回到前台时候调用");
- }
⑦当程序将要退出是被调用,通常是用来保存数据和一些退出前的清理工作。这个需要要设置UIApplicationExitsOnSuspend的键值
- - (void)applicationWillTerminate:(UIApplication *)application
- {
-
- NSLog(@"⑦当程序将要退出是被调用");
- }
⑧当程序载入后执行
- - (void)applicationDidFinishLaunching:(UIApplication *)application
- {
- NSLog(@"⑧当程序载入后执行");
- }
程序启动时:
2014-07-01 15:55:14.706 LifeCycle[5845:60b] ①告诉代理进程启动但还没进入状态保存
2014-07-01 15:55:14.708 LifeCycle[5845:60b] ②告诉代理启动基本完成程序准备开始运行
2014-07-01 15:55:14.709 LifeCycle[5845:60b] ④当应用程序进入活动状态执行
按下Home键返回主界面:
2014-07-01 15:56:11.756 LifeCycle[5845:60b] ③当应用程序将要入非活动状态执行
2014-07-01 15:56:11.814 LifeCycle[5845:60b] ⑤当程序被推送到后台的时候调用
再次打开程序:
2014-07-01 15:57:19.200 LifeCycle[5845:60b] ⑥当程序从后台将要重新回到前台时候调用
2014-07-01 15:57:19.201 LifeCycle[5845:60b] ④当应用程序进入活动状态执行
3、加载应用程序进入前台
4、加载应用程序进入后台
5、基于警告式响应中断
当出现这种中断时,我们需要在- (void)applicationWillResignActive:(UIApplication *)application方法中进行如下操作:
①停止timer 和其他周期性的任务
②停止任何正在运行的请求
③暂停视频的播放
④如果是游戏那就暂停它
⑤减少OpenGL ES的帧率
⑥挂起任何分发的队列和不重要的操作队列(你可以继续处理网络请求或其他时间敏感的后台任务)
当程序回到active状态,我们需要在- (void)applicationDidBecomeActive:(UIApplication *)application方法中重新开始上述任务。不过游戏要回到暂停状态,不能自动开始。
6、进入后台运行
当应用程序进入后台时,我们应该做些什么?
保存用户数据或状态信息,所有没写到磁盘的文件或信息,在进入后台时,最后都写到磁盘去,因为程序可能在后台被杀死。
释放尽可能释放的内存。
- (void)applicationDidEnterBackground:(UIApplication *)application方法有大概5秒的时间让你完成这些任务。如果超过时间还有未完成的任务,你的程序就会被终止而且从内存中清除。
如果还需要长时间的运行任务,可以在该方法中调用
- [application beginBackgroundTaskWithExpirationHandler:^{
-
- NSLog(@"begin Background Task With Expiration Handler");
-
- }];
应用程序在后台时的内存使用:请求后台运行时间和启动线程来运行长时间运行的任务。
在后台时,每个应用程序都应该释放最大的内存。系统努力的保持更多的应用程序在后台同时 运行。不过当内存不足时,会终止一些挂起的程序来回收内存,那些内存最大的程序首先被终止。
事实上,应用程序应该的对象如果不再使用了,那就应该尽快的去掉强引用,这样编译器可以回收这些内存。如果你想缓存一些对象提升程序的性能,你可以在进入后台时,把这些对象去掉强引用。
下面这样的对象应该尽快的去掉强引用:
①图片对象
②你可以重新加载的 大的视频或数据文件
③任何没用而且可以轻易创建的对象
在后台时,为了减少程序占用的内存,系统会自动在回收一些系统帮助你开辟的内存。比如:
①系统回收Core Animation的后备存储。
②去掉任何系统引用的缓存图片
③去掉系统管理数据缓存强引用
7、返回前台运行
在暂停状态的应用程序必须准备处理任何排队的通知时,它返回到前台或后台执行状态。暂停的应用程序不执行任何代码,因此不能处理与方向的变化, 时间的变化,偏好的变化,以及许多其他会影响应用程序的外观或状态的通知。为了确保这些更改不会丢失,系统排队许多相关的通知,并把它们传递给应用程序, 只要它开始再次执行代码(无论是在前景或背景)。为了防止由偏快转为超载与它恢复时通知您的应用程序,该系统凝聚事件,并提供一个单一的通知(每个相关类 型),反映了净变化,因为你的应用程序被暂停。
8、程序终止
程序只要符合以下情况之一,只要进入后台或挂起状态就会终止:
①iOS4.0以前的系统
②app是基于iOS4.0之前系统开发的。
③设备不支持多任务
④在Info.plist文件中,程序包含了 UIApplicationExitsOnSuspend 键。
app如果终止了,系统会调用app的代理的方法 - (void)applicationWillTerminate:(UIApplication *)application,这样可以让你可以做一些清理工作。你可以保存一些数据或app的状态。这个方法也有5秒钟的限制。超时后方法会返回程序从内 存中清除。
注意:用户可以手工关闭应用程序。
9、The Main Run Loop 主运行循环
Main Run Loop负责处理用户相关的事件。UIApplication对象在程序启动时启动main run Loop,它处理事件和更新视图的界面。看Main Run Loop就知道,它是运行在程序的主线程上的。这样保证了接收到用户相关操作的事件是按顺序处理的。
用户操作设备,相关的操作事件被系统生成并通过UIKit的指定端口分发。事件在内部排成队列,一个个的分发到Main run loop 去做处理。UIApplication对象是第一个接收到时间的对象,它决定事件如何被处理。触摸事件分发到主窗口,窗口再分发到对应出发触摸事件的 View。其他的事件通过其他途径分发给其他对象变量做处理。
大部分的事件可以在你的应用里分发,类似于触摸事件,远程操控事件(线控耳机等)都是由app的 responder objects 对象处理的。Responder objects 在你的app里到处都是,比如:UIApplication 对象,view对象,view controller 对象,都是resopnder objects。大部分事件的目标都指定了resopnder object,不过事件也可以传递给其他对象。比如,如果view对象不处理事件,可以传给父类view或者view controller。
iOS-App生命周期
标签:
原文地址:http://www.cnblogs.com/Samboo/p/5348890.html