應用程序的生命週期

以前對於應用程序的生命週期,和Appdelegate類在應用程序的不一樣階段回調的不一樣方法一直存在這很大疑問,今天下午特地查閱相關資料對此瞭解。app

先從一個程序的啓動提及吧ide

 

1.Not running(非運行狀態) -----》2.inactive(前臺非活躍狀態)----------》3.Active(前臺活躍狀態)-------》Background (後臺狀態) --------》suspended(掛起狀態)函數

 

       固然這些箭頭並非單向的,不一樣的場景會有不一樣的方式ui

好比說可能從Background (後臺狀態) ----》inactive(前臺非活躍狀態);this

再好比說從suspended(掛起狀態)------》Background (後臺狀態) ;spa

固然在發出內存警告,或者用戶主動關閉後臺程序時會從suspended(掛起狀態)---》Not running(非運行狀態)。翻譯

 

1.Not running (非運行狀態):咱們的應用沒有運行。代理

2.Inactive(前臺非活躍狀態):應用程序正在進入前臺,但還不能接受事件的處理。rest

3.Active(前臺活躍狀態):應用程序進入前臺狀態,並且能接受事件的處理code

4.Background(後臺狀態):應用進入後臺,依然可以執行代碼,可是一旦執行玩可執行的代碼,應用立刻就會進入咱們常說的掛起狀態。

5.Suspended(掛起狀態):處於該狀態的程序,彷彿進入了一種冰凍狀態,不能執行代碼。且若是系統的內存不夠,應用程序會被終止。

 

    下面咱們也說說AppDelegate中那些代理方法,我把項目中的註釋在網上翻譯了一下,感受並不怎麼好,因而有查閱了我最近買的一本書。感受還勉強能把那些方法說明白點吧。

//  Copyright (c) 2015年 王志豪imac. All rights reserved.
//

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

//app加載完畢的時候調用(通常只調用一次)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //翻譯: 應用程序啓動後覆蓋點定製
    // Override point for customization after application launch.
    
    //說明: 應用程序啓動並進行初始化時調用的方法,這個階段會實例化根視圖控制器
    NSLog(@"程序加載完畢");
    
    
    
    return YES;
}
//程序失去焦點的時候調用(控件不能接受事件)
- (void)applicationWillResignActive:(UIApplication *)application {
    
    
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    //翻譯:發送時,應用程序是從活動到非活動狀態。這可能會出現某些類型的臨時中斷(如來電或短信)或當用戶退出應用程序,它開始過渡到背景狀態(後臺)
    
    
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    //翻譯:用這種方法來暫停正在進行的任務,禁用定時器,和油門下的OpenGL ES的幀速率。遊戲應該用這種方法來暫停遊戲
    
    NSLog(@"程序失去焦點");
    
    //說明 : 應用程序從活躍狀態到非活躍狀態時調用,這個階段能夠保存UI狀態(例如遊戲狀態)
}


//app進入後臺的時候調用(app消失不見)
- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    //翻譯:用這種方法釋放共享資源,保存用戶數據,無效計時器,並儲存足夠的應用程序狀態信息來恢復您的應用程序的當前狀態的狀況下,終止後。
    
    
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    //翻譯:若是您的應用程序支持後臺執行,這種方法被稱爲替代applicationWillTerminate:當用戶退出。  (注:applicationWillTerminate 是當程序結束時調用的方法,通常狀況下不會調用)
    
    NSLog(@"程序進入後臺");
    
    //說明: 應用程序進入後臺時調用,該方法。這個階段能夠保存用戶數據,釋放一些資源(例如釋放數據資源庫)
}

//當app進入前臺的時候調用的方法(app顯示出來)
- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    
    //翻譯:稱爲從背景(後臺)到非活動狀態的過渡的一部分;在這裏,您能夠撤消進入背景(後臺)的許多更改。
    
    //說明: 應用程序進入前臺,可是尚未處於活動狀態,這個階段能夠恢復用戶數據
    NSLog(@"程序進入前臺");
}

//當程序得到焦點的時候調用(只有程序得到焦點  全部的控件才能接受事件)
- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    //翻譯:從新啓動任何已暫停的任務(或還沒有開始),而應用程序處於非活動狀態。若是應用程序在後臺,能夠隨意刷新用戶界面。
    //說明: 應用程序進入前臺,並處於活動狀態時調用的方法,這個階段能夠恢復UI的狀態。(例如遊戲的狀態)。
    NSLog(@"程序得到焦點");
}


//當程序結束的時候調用(通常不會調用,)當程序進入後臺,時會進入休眠狀態,要想調用這個方法,必須把休眠狀態關掉。(把Info.plist中的Application does not run in background改成YES就行默認爲NO)
- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    //翻譯:當應用程序即將終止時調用。若是適當的話,保存數據。又見applicationDidEnterBackground有
    
    NSLog(@"程序結束");
    
    //說明: 應用程序被終止,時調用,但內存清除時除外,這個階段能夠釋放一些資源,也可保存用戶數據。
}

@end

其實這看代碼並不能清楚他們之間到底何時調用。

下面我也學學那些大神們模擬幾個場景,可能不是太準確,但至少也算可以說明狀況。

  1》非運行狀態-----》到應用啓動

     當你點擊APP圖標,或者說,你運行程序吧。固然也多是從後臺到前臺。

在這個過程當中:主要有下面三個狀態

Not running(非運行狀態)-------->Inactive(前臺非活躍狀態)------------->Active(前臺活躍狀態)

 

在Not running(非運行狀態)-------->Inactive(前臺非活躍狀態)時:

//app加載完畢的時候調用(通常只調用一次)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //翻譯: 應用程序啓動後覆蓋點定製
    // Override point for customization after application launch.
    
    //說明: 應用程序啓動並進行初始化時調用的方法,這個階段會實例化根視圖控制器
    NSLog(@"程序加載完畢");
    
    
    
    return YES;
}

Inactive(前臺非活躍狀態)------------->Active(前臺活躍狀態)時調用:

 

//當程序得到焦點的時候調用(只有程序得到焦點  全部的控件才能接受事件)
- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    //翻譯:從新啓動任何已暫停的任務(或還沒有開始),而應用程序處於非活動狀態。若是應用程序在後臺,能夠隨意刷新用戶界面。
    //說明: 應用程序進入前臺,並處於活動狀態時調用的方法,這個階段能夠恢復UI的狀態。(例如遊戲的狀態)。
    NSLog(@"程序得到焦點");
}
2》點擊Home建 ---------應用消失不見(後臺)
     固然這裏的場景是在應用處於(前臺活躍狀態)時點擊Home鍵。又或者說其餘應用致使當前正在運行的程序中斷。
其實這個狀況仍是有點複雜的。首先程序進入後臺後 有倆種狀況,以前我也是迷惑了一段,感受有必要把他的前因後果摸清楚了。在屬性文件(Info.plist)中有一個叫作 Application does not run in background的屬性(默認是NO)也就是應用程序能夠在後臺運行或者掛起。一樣若是設置成YES應用程序不能夠在後臺運行或者掛起。
你能夠參照下圖去設置一下,試試效果如何。

 

說完上面的一些大體場景,那麼讓我先從第一種狀況:應用程序能夠在後臺運行或者掛起提及吧。
這個階段主要有四個狀態:
從Active(前臺活躍狀態)---->Inactive(前臺非活躍狀態)---------->Background(後臺狀態)----->Suspended(掛起狀態);
第一階段:從Active(前臺活躍狀態)---->Inactive(前臺非活躍狀態)調用:
//程序失去焦點的時候調用(控件不能接受事件)
- (void)applicationWillResignActive:(UIApplication *)application {
    
    
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    //翻譯:發送時,應用程序是從活動到非活動狀態。這可能會出現某些類型的臨時中斷(如來電或短信)或當用戶退出應用程序,它開始過渡到背景狀態(後臺)
    
    
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    //翻譯:用這種方法來暫停正在進行的任務,禁用定時器,和油門下的OpenGL ES的幀速率。遊戲應該用這種方法來暫停遊戲
    
    NSLog(@"程序失去焦點");
    
    //說明 : 應用程序從活躍狀態到非活躍狀態時調用,這個階段能夠保存UI狀態(例如遊戲狀態)
}
第二階段:Inactive(前臺非活躍狀態)---------->Background(後臺狀態)
這個階段我也不清楚調用什麼方法。
 
第三階段:Background(後臺狀態)----->Suspended(掛起狀態)調用
//app進入後臺的時候調用(app消失不見)
- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    //翻譯:用這種方法釋放共享資源,保存用戶數據,無效計時器,並儲存足夠的應用程序狀態信息來恢復您的應用程序的當前狀態的狀況下,終止後。
    
    
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    //翻譯:若是您的應用程序支持後臺執行,這種方法被稱爲替代applicationWillTerminate:當用戶退出。  (注:applicationWillTerminate 是當程序結束時調用的方法,通常狀況下不會調用)
    
    NSLog(@"程序進入後臺");
    
    //說明: 應用程序進入後臺時調用,該方法。這個階段能夠保存用戶數據,釋放一些資源(例如釋放數據資源庫)
}
那麼讓咱們接着說第二種狀況吧
應用程序不能夠在後臺運行或者掛起。
Active(前臺活躍狀態)------>Inactive(前臺非活躍狀態)--------->Background(後臺狀態)----->Suspended(掛起狀態)-------->Not running (非運行狀態);
這種狀況,一共五個狀態四個階段。
 
第一階段:Active(前臺活躍狀態)------>Inactive(前臺非活躍狀態):

 

 
//程序失去焦點的時候調用(控件不能接受事件)
- (void)applicationWillResignActive:(UIApplication *)application {
    
    
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    //翻譯:發送時,應用程序是從活動到非活動狀態。這可能會出現某些類型的臨時中斷(如來電或短信)或當用戶退出應用程序,它開始過渡到背景狀態(後臺)
    
    
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    //翻譯:用這種方法來暫停正在進行的任務,禁用定時器,和油門下的OpenGL ES的幀速率。遊戲應該用這種方法來暫停遊戲
    
    NSLog(@"程序失去焦點");
    
    //說明 : 應用程序從活躍狀態到非活躍狀態時調用,這個階段能夠保存UI狀態(例如遊戲狀態)
第二階段:Inactive(前臺非活躍狀態)--------->Background(後臺狀態)調用
還不清楚,調用什麼方法。
 
第三階段Background(後臺狀態)----->Suspended(掛起狀態)
//app進入後臺的時候調用(app消失不見)
- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    //翻譯:用這種方法釋放共享資源,保存用戶數據,無效計時器,並儲存足夠的應用程序狀態信息來恢復您的應用程序的當前狀態的狀況下,終止後。
    
    
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    //翻譯:若是您的應用程序支持後臺執行,這種方法被稱爲替代applicationWillTerminate:當用戶退出。  (注:applicationWillTerminate 是當程序結束時調用的方法,通常狀況下不會調用)
    
    NSLog(@"程序進入後臺");
    
    //說明: 應用程序進入後臺時調用,該方法。這個階段能夠保存用戶數據,釋放一些資源(例如釋放數據資源庫)
}
第四階段:Suspended(掛起狀態)-------->Not running (非運行狀態)調用

 

//當程序結束的時候調用(通常不會調用,)當程序進入後臺,時會進入休眠狀態,要想調用這個方法,必須把休眠狀態關掉。(把Info.plist中的Application does not run in background改成YES就行默認爲NO)
- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    //翻譯:當應用程序即將終止時調用。若是適當的話,保存數據。又見applicationDidEnterBackground有
    
    NSLog(@"程序結束");
    
    //說明: 應用程序被終止,時調用,但內存清除時除外,這個階段能夠釋放一些資源,也可保存用戶數據。
}
上面那個場景不知道描述的夠不夠準確,可能有好多不足之處。
當從 後臺(掛起)到應用從新運行起來。也會調用一些方法
uspended(掛起狀態)-----》Background(後臺狀態)————》Inactive(前臺非活躍狀態)————》Active(前臺活躍狀態)
第一階段我不是太清楚調用了什麼方法。
 
第二階段,Background(後臺狀態)————》Inactive(前臺非活躍狀態)
調用了

 

 
//當app進入前臺的時候調用的方法(app顯示出來)
- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    
    //翻譯:稱爲從背景(後臺)到非活動狀態的過渡的一部分;在這裏,您能夠撤消進入背景(後臺)的許多更改。
    
    //說明: 應用程序進入前臺,可是尚未處於活動狀態,這個階段能夠恢復用戶數據
    NSLog(@"程序進入前臺");
}

 

第三階段:Inactive(前臺非活躍狀態)————》Active(前臺活躍狀態)
//當程序得到焦點的時候調用(只有程序得到焦點  全部的控件才能接受事件)
- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    //翻譯:從新啓動任何已暫停的任務(或還沒有開始),而應用程序處於非活動狀態。若是應用程序在後臺,能夠隨意刷新用戶界面。
    //說明: 應用程序進入前臺,並處於活動狀態時調用的方法,這個階段能夠恢復UI的狀態。(例如遊戲的狀態)。
    NSLog(@"程序得到焦點");
}
基本上以上場景都能說明問題了。
 
不過還有一種狀況,這種狀況不多發生,就是當你在玩手機時,發出內存警告,爲了解決內存問題,會把你在後臺掛起的程序終止。在這裏我也就不模擬場景了。
 
    其實我想說的是另一種狀況就是程序加載完成時調用的方法。實在是不想打字了,複製我之前作的筆記了,也能夠說明一些狀況。
 

程序啓動的完整過程

1.main函數

 

2.UIApplicationMain

*建立UIApplication對象

*建立UIApplication的delegate對象

 

3.delegate對象開始處理(監聽)系統事件(沒有storyboard的狀況)

*程序啓動完畢的時候, 就會調用代理的application:didFinishLaunchingWithOptions:方法

*在application:didFinishLaunchingWithOptions:中建立UIWindow

*建立和設置UIWindow的rootViewController

* 顯示窗口

 

3.根據Info.plist得到最主要storyboard的文件名,加載最主要的storyboard(有storyboard)

*建立UIWindow

*建立和設置UIWindow的rootViewController

* 顯示窗口

這樣咱們的程序就能顯示在手機屏幕上了。
 

 

-------------------代碼永無止境。

相關文章
相關標籤/搜索