iOSアプリケーションのライフサイクル
アプリケーションの状態
IOSアプリケーションには5つの状態があります。
- 実行されていません:プログラムは開始されていません
- 非アクティブ:他の2つの状態が切り替わるときに表示される一時的な状態。この状態を長時間続ける唯一の時間は、ユーザーが画面をロックしたときですか?または、システムはユーザーに警告ウィンドウ(着信、メッセージなど)に応答するように求めます
- アクティブ:画面に表示される通常の動作状態。ユーザー入力を受け取り、表示を更新できます。
- 背景:プログラムはバックグラウンドにあり、コードを実行できます。ユーザーは、ホームボタンを押した直後にこの状態に入り(最初に非アクティブ状態に入り、次にバックグラウンド状態に入ります)、すぐにサスペンド状態に入ります。一部のプログラムは、特別な要求の後、長期間Backgroud状態にとどまることができます
- 一時停止:プログラムはバックグラウンドでコードを実行できません。通常のプログラムは、バックグラウンド状態に入った直後にこの状態に入ります。一時停止しても、プログラムはメモリ内に残ります。システムメモリが少ない場合、システムは一時停止したプログラムをクリアして、フォアグラウンドプログラム用のメモリを増やします。
この図は非常に重要であり、すべての矢印は慎重に検討する必要があります。
アクティブと非アクティブの切り替えについて:
アプリケーションがフォアグラウンドにある場合、アクティブと非アクティブの2つの状態があります。ほとんどの場合、非アクティブ状態は、他の2つの状態が切り替わったときに表示される短期間のみの状態です(図に示すように、2つの状態間の切り替えが非アクティブになるわけではありません)。アプリケーションを開くと、アプリケーションは最初に非実行から非アクティブに入り、次にアクティブ;たとえば、前面と背面のアプリケーションを切り替えると、非アクティブがアクティブとバックグラウンドの間に短時間表示されます。
ただし、他の状況もあります。フォアグラウンドで実行しているときにアクティブと非アクティブを切り替えることができます。たとえば、システムがアラートをポップアップすると、ユーザーが確認してからActvieに戻るまで、アプリケーションはアクティブから非アクティブに切り替わります。ユーザーが通知ページをプルダウンすると、アクティブも発生します。非アクティブでの切り替え。着信はあるが拒否され、ホームボタンをダブルクリックしても元のアプリケーションに戻るなど、バックグラウンドに移行せず、アクティブと非アクティブを切り替えるだけです。
図に示すように、アクティブにしたい場合は、最初に非アクティブを入力する必要があると言えますか?
エントリー機能
int main(int argc、char * argv []) { @autoreleasepool { return UIApplicationMain(argc、argv、nil、NSStringFromClass([XYZAppDelegate class ])); } }
// If nil is specified for principalClassName, the value for NSPrincipalClass from the Info.plist is used. If there is no // NSPrincipalClass key specified, the UIApplication class is used. The delegate class will be instantiated using init. UIKIT_EXTERN int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);
argc和argv是为了与C语言保持一致,在这没用到,不详述。
后面两个参数为principalClassName(主要类名)和delegateClassName(委托类名)。
如果principalClassName是nil,那么它的值将从Info.plist中获取,如果Info.plist中没有,则默认为UIApplication。principalClass这个类除了管理整个程序的生命周期之外什么都不做,它只赋值监听事件然后交给delegateClass去做。
而delegateClass将在工程新建时实例化一个对象。
NSStringFromClass([XYZAppDelegate class])
相当于@"XYZAppDelegate"。
AppDelegate类六个方法
注意代码中的官方注释。
启动程序
2014-07-28 15:22:39.883 LifeCycle[3024:a0b] didFinishLaunchingWithOptions
2014-07-28 15:22:39.887 LifeCycle[3024:a0b] DidBecomeActive
按下Home键
2014-07-28 15:22:43.130 LifeCycle[3024:a0b] WillResignActive
2014-07-28 15:22:43.131 LifeCycle[3024:a0b] DidEnterBackground
重新点击程序
2014-07-28 15:22:44.380 LifeCycle[3024:a0b] WillEnterForeground
2014-07-28 15:22:44.380 LifeCycle[3024:a0b] DidBecomeActive
注意:
- 启动程序并没有调用WillEnterForeground这个方法。
- 并不是所有状态切换都有相应的方法来通知,比如从Background到Suspended。所以当你按下Home键的时候,我们只知道调用了WillResignActive和DidEnterBackground方法,但其实应用程序会迅速从Background进入Suspended。
1.application:didFinishLaunchingWithOptions:
程序首次已经完成启动时执行,若直接启动,launchOptions中没有数据;否则,launchOptions将包含对应方式的内容(比如从微信中启动节奏大师--)。
2.applicationWillResignActive(将进入后台)
程序将要失去Active状态时调用,比如按下Home键或有电话信息进来。对应applicationWillEnterForeground(将进入前台),这个方法用来
- 暂停正在执行的任务;
- 禁止计时器;
- 减少OpenGL ES帧率;
- 若为游戏应暂停游戏;
总结为一个字:停!
3.applicationDidEnterBackground(已经进入后台)
程序已经进入后台时调用,对应applicationDidBecomeActive(已经变成前台),这个方法用来
- 释放共享资源;
- 保存用户数据(写到硬盘);
- 作废计时器;
- 保存足够的程序状态以便下次恢复;
总结为4个字:释放、保存!
4.applicationWillEnterForeground(将进入前台)
程序即将进去前台时调用,对应applicationWillResignActive(将进入后台)。这个方法用来撤销applicationWillResignActive中做的改变。
5.applicationDidBecomeActive(已经进入前台)
程序已经变为Active(前台)时调用。对应applicationDidEnterBackground(已经进入后台)。若程序之前在后台,最后在此方法内刷新用户界面。
6.applicationWillTerminate
程序即将退出时调用。记得保存数据,如applicationDidEnterBackground方法一样。
如果你的类是AppDelegate类(声明遵循UIApplicationDelegate协议),那么可以实现上面的6个方法,当App状态改变的时候相应的方法会被调用;如果你的类不是AppDelegate类,那么该类如何知道App的各种状态变化,以及如何使用这些函数呢?答案是使用NotificationCenter来通知。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive) name:UIApplicationWillResignActiveNotification object:[UIApplication sharedApplication]];
然后实现applicationWillResignActive就行了
- (void)applicationWillResignActive //自定义的函数 { NSLog(@"%@", NSStringFromSelector(_cmd)); }