作為應用程序的委托對象,AppDelegate類在應用生命周期的不同階段會回調不同的方法。首先,讓我們先了解一下iOS 應用的不同狀態及它們彼此間的關系,見圖1 。

圖1 iOS應用狀態圖
下面簡要介紹一下iOS 應用的5種狀態。
Not Running(非運行狀態)。應用沒有運行或被系統終止。
Inactive (前台非活動狀態)。應用正在進入前台狀態,但是還不能接受事件處理。
Active (前台活動狀態)。應用進入前台狀態,能接受事件處理。
Background(后台狀態)。應用進入后台后,依然能夠執行代碼。如果有可執行的代碼,就會執行代碼,如果沒有可執行的代碼或者將可執行的代碼執行完畢,應用會馬上進入掛起狀態。
Suspended(掛起狀態)。處於掛起的應用進入一種“冷凍”狀態,不能執行代碼。如果系統內存不夠,應用會被終止。
在應用狀態躍遷的過程中,iOS 系統會回調AppDelegate中的一些方法,並且發送一些通知。實際上,在應用的生命周期中用到的方法和通知很多,我們選取了幾個主要的方法和通知進行詳細介紹,具體如表1所述。
表1 狀態躍遷過程中應用回調的方法和本地通知

為了便於觀察應用程序的運行狀態,我們為AppDelegate.m中的方法添加一些日志輸出,具體代碼如下:
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(@"%@", @"application:didFinishLaunchingWithOptions:");
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
NSLog(@"%@", @"applicationWillResignActive:");
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(@"%@", @"applicationDidEnterBackground:");
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(@"%@", @"applicationWillEnterForeground:");
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSLog(@"%@", @"applicationDidBecomeActive:");
}
- (void)applicationWillTerminate:(UIApplication *)application
{
NSLog(@"%@", @"applicationWillTerminate:");
}
@end
為了讓大家更直觀地了解各狀態與其相應的方法、通知間的關系,下面我們以幾個應用場景為切入點進行系統的分析。
(一)非運行狀態——應用啟動場景
場景描述:用戶點擊應用圖標的時候,可能是第一次啟動這個應用,也可能是應用終止后再次啟動。該場景的狀態躍遷過程見圖2 ,共經歷兩個階段3個狀態:Not running →Inactive→Active。
在Not running→Inactive 階段。調用application:didFinishLaunchingWithOptions:方法,發出UIApplicationDidFinishLaunchingNotification 通知。
在Inactive →Active 階段。調用 applicationDidBecomeActive: 方法,發出UIApplicationDidBecomeActiveNotification 通知。

圖2 應用啟動場景的狀態躍遷過程
(二)點擊Home鍵——應用退出場景
場景描述:應用處於運行狀態(即Active狀態)時,點擊Home鍵或者有其他的應用導致當前應用中斷。該場景的狀態躍遷過程可以分成兩種情況:可以在后台運行或者掛起,不可以在后台運行或者掛起。根據產品屬性文件(如HelloWorld-Info.plist)中的相關屬性Application does not run in background 是與否可以控制這兩種狀態。如果采用文本編輯器打開HelloWorldInfo.plist文件該設置項對應的鍵是UIApplicationExitsOnSuspend。
狀態躍遷的第一種情況:應用可以在后台運行或者掛起,該場景的狀態躍遷過程見圖3 ,共經歷3 個階段4個狀態:Active → Inactive → Background→Suspended。
在Active→Inactive 階段。調用 applicationWillResignActive:方法,發出UIApplicationWillResignActiveNotification 通知。
在Inactive →Background階段。應用從非活動狀態進入到后台(不涉及我們要重點說明的方法和通知)。
在Background→Suspended 階段。調用applicationDidEnterBackground:方法,發出UIApplicationDidEnterBackgroundNotification 通知。

圖3 點擊Home鍵應用退出場景
狀態躍遷的第二種情況:應用不可以在后台運行或者掛起,其狀態躍遷情況見圖4 ,共經歷4個階段5 個狀態:Active → Inactive → Background→Suspended→Not running 。
在Active →Inactivd 階段。應用由活動狀態轉為非活動狀態(不涉及我們要重點說明的方法和通知)。
在Inactive →Background階段。應用從非活動狀態進入到后台(不涉及我們要重點說明的方法和通知)。
在Background→Suspended 階段。調用applicationDidEnterBackground:方法, 發出UIApplicationDidEnterBackgroundNotification 通知。
在Suspended →Not running階段。調用applicationWillTerminate:方法,發出UIApplicationWillTerminateNotification通知。

圖4 點擊Home鍵,應用退出場景
iOS 在iOS 4之前不支持多任務,點擊Home鍵時,應用會退出並中斷;而在iOS 4之后(包括iOS 4),操作系統能夠支持多任務處理,點擊Home鍵應用會進入后台但不會中斷(內存不夠的情況除外)。
應用在后台也可以進行部分處理工作,處理完成則進入掛起狀態。
(三)掛起重新運行場景
場景描述:掛起狀態的應用重新運行。該場景的狀態躍遷過程如圖5 所示,共經歷3 個階段4 個狀態:Suspended → Background → Inactive → Active 。

圖5 重新運行場景的狀態躍遷過程
Suspended→Background階段。應用從掛起狀態進入后台(不涉及我們講述的這幾個方法和通知)。
Background→Inactive 階段。調用applicationWillEnterForeground: 方法,發出UIApplicationWillEnterForegroundNotification通知。
Inactive →Active 階段。調用applicationDidBecomeActive:方法,發出UIApplicationDidBecomeActiveNotification 通知。
(四)內存清除——應用終止場景
場景描述:應用在后台處理完成時進入掛起狀態(這是一種休眠狀態),如果這時發出低內存警告,為了滿足其他應用對內存的需要,該應用就會被清除內存從而終止運行,該場景的狀態躍遷見圖6 。

圖6 內存清除終止場景
內存清除的時候應用終止運行。內存清除有兩種情況,可能是系統強制清除內存,也可能是由使用者從任務欄中手動清除(即刪掉應用)。內存清除后如果應用再次運行,上一次的運行狀態不會被保存,相當於應用第一次運行。
在內存清除場景下,應用不會調用任何方法,也不會發出任何通知。
