iOS APP的生命週期

b10l07發表於2018-09-09
本文參考的蘋果文件

UIApplication

UIApplicationMain

UIApplicationDelegate

Managing Your App's Life Cycle


11158342-380ee788696f57af.jpg
博文配圖

1. UIApplication

每一個 iOS app 都會有一個UIApplication的例項(或者是UIApplication的子類,不過這種情況很少很少)。當一個app啟動的時候,系統會呼叫 UIApplicationMain 函式,這個函式會建立一個單例 UIApplication 物件你可以通過呼叫 sharedApplication 這個類方法來訪問這個單例 UIApplication 物件

UIApplication 物件的一個重要作用就是作為處理到來的使用者事件的初始路由(也就是一個轉發事件的作用):

  • 它可以將 UIControl 類物件傳送給它的動作訊息再派發給合適的目標物件
  • UIApplication 物件維持一個或多個UIWindow物件,並且可以通過UIWindow物件檢索UIView物件

UIApplication類定義了一個代理,即UIApplicationDelegate(使用它必須遵守UIApplicationDelegate協議並且實現一些方法)。

UIApplication物件會通知UIApplicationDelegate重要的執行時事件(runtime events),並讓UIApplicationDelegate進行反應處理,比如,app啟動、記憶體過低、app終止等。

2. UIApplicationMain函式

蘋果文件--UIApplicationMain函式

app的入口為main.m裡的main函式

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

main函式執行並返回的是一個 UIApplicationMain 函式

int UIApplicationMain(int argc, char * _Nullable *argv, NSString *principalClassName, NSString *delegateClassName);

儘管宣告瞭返回型別,但此函式永遠不會返回

UIApplicationMain 函式可以

  • 例項化 Application 物件

  • 例項化並設定 Appledelegate

  • 設定主執行緒對應的 RunLoop,並且開始處理事件

  • 如果Info.plist檔案中指定了要載入的main nib檔案,通過 NSMainNibFile key 和一個有效nib檔名,這個函式將載入這個nib檔案

3. UIApplicationDelegate

UIApplicationDelegate要和UIApplication一起使用。

UIApplicationDelegate裡的方法可以讓你響應app一些重要的變化,例如,你可以使用UIApplicationDelegate裡的一些方法去應對app狀態的改變(比如當從前臺移動到後臺的時候),也可以對到來的通知進行響應****。大多數的情況下,UIApplicationDelegate是接收這些通知的唯一途徑

Xcode預設為一個新專案提供了一個UIApplicationDelegate(即AppDelegate類),所以你不需要去自定義。當app啟動的時候,UIKit會自動建立一個UIApplicationDelegate類的例項,並且執行裡面的自定義程式碼。

UIApplicationDelegate實際上是app的根物件(the root object),並且和UIApplication物件一樣,都是一個單例,並且始終存在於執行時(Runtime)。

UIApplication物件完成app的大部分底層工作,你可以通過UIApplicationDelegate的方法去管理app的整體行為。

UIApplicationDelegate扮演的關鍵角色

  • 包含了app的啟動程式碼
  • 響應app的狀態轉變
  • 響應來自app外部的通知,比如記憶體過低警告、下載完成的通知等等
  • 它可以進行狀態的儲存和恢復;這點可以看Preserving Your App's UI Across Launches
  • 它可以響應針對app本身的事件,並不特定於view或viewController;
  • 可以使用它儲存app的中央資料物件或任何沒有它自己的viewcontroller的一些內容。

3.1 啟動應用程式

Launch time(啟動時間)是應用生命週期重要的一個點。在啟動時間,Appdelegate會負責執行初始化app的自定義程式碼,例如:Appdelegate會建立app的初始化資料結構,註冊所需要的服務,根據資料調整app的初始化介面。

Appdelegate在Launch time(啟動時間)的一些任務:

  • application:willFinishLaunchingWithOptions: and application:didFinishLaunchingWithOptions:,這兩個方法裡的options引數是一個字典,裡面有app被啟動的原因,系統會檢視啟動原因
  • 確定是否繼續進行狀態恢復。application:shouldRestoreApplicationState:
  • 註冊遠端通知。 registerForRemoteNotificationTypes:
  • 開啟傳送到app的網址。application:openURL:options:
  • 為app提供一個根視窗物件(the root window object)。實際上,Xcode預設提供了一個UIWindow,當然你也可以自定義一個keyWindow。

3.2 管理APP的狀態

AppDelegate的主要工作之一就是響應由系統通知的狀態轉換。當狀態轉換髮生時,系統會呼叫AppDelegate的相應方法。每一種狀態都有相應的規則去管理app的執行行為,並且AppDelegate會呼叫相應的方法

3.2.1 app有五種狀態
  • Not running(未執行狀態)app未啟動或者被終止(無論是被系統還是使用者)。
  • Inactive(不活躍狀態):app在前臺執行但未接收事件。app只在轉換到不同狀態時會短暫地保持此狀態。進入此狀態後,app會很快進入後臺(Background)或活動(Active)狀態。(打電話時或者下拉通知欄時app會進入此狀態)
  • Active(活動狀態):app在前臺執行並且正在接收事件。處於前臺的app通常狀態就是Active。
  • Background(後臺狀態):app在螢幕上不可見但是正在執行程式碼,這是後臺狀態。當使用者退出應用後(應該是按home鍵),系統會將app在掛起(suspend)前短暫地移動到後臺(Background)狀態。
  • Suspended(掛起狀態):應用程式在記憶體中,但不執行程式碼。系統會掛起在後臺(Background)狀態的應用程式。系統可能會為了騰出記憶體空間,將app清除出記憶體
3.2.2 狀態轉換圖
11158342-0487f4153d2f8751.png
app 狀態轉換圖

圖解:

  1. 應用程式(app)在前臺有 Inactive 和 Active 兩種狀態;
  2. Not running 在進入 Active 前,會短暫停留在 Inactive 狀態;
  3. Active 狀態進入 Background 狀態前,會短暫地保持 Inactive 狀態;
  4. Background 狀態會迅速進入 Suspended 狀態;
  5. Suspended 狀態下系統有可能將其清除,進入 Not running 狀態。

3.3 狀態轉換時,系統會呼叫的方法

在狀態轉換時會呼叫下列方法,以下方法都是Appdelegate的方法:

  1. 啟動應用程式時(Launch time),
application:willFinishLaunchingWithOptions:
application:didFinishLaunchingWithOptions:
  1. 轉換到Active狀態,
applicationDidBecomeActive:
  1. 轉換到Background狀態,
applicationDidEnterBackground:
  1. 轉換到Inactive狀態
applicationWillResignActive:(當離開前臺狀態的時候呼叫)
applicationWillEnterForeground:(當從後臺狀態轉到前臺狀態時呼叫)
  1. 終止
applicationWillTerminate:(這個方法只會在app執行時呼叫,app被掛起時不會被呼叫)

3.4

初次啟動app會呼叫:

application:willFinishLaunchingWithOptions:
application:didFinishLaunchingWithOptions:
applicationDidBecomeActive:

按下home鍵(從前臺退出到Background狀態):

applicationWillResignActive:(當離開前臺狀態的時候呼叫)
applicationDidEnterBackground:

再次點選進入app:

applicationWillEnterForeground:(當從後臺狀態轉到前臺狀態時呼叫)
applicationWillResignActive:(當離開前臺狀態的時候呼叫)

4. 生命週期

11158342-845a2be4a8c62760.png
圖示

圖解:

點選app按鈕,應用程式啟動;

執行main函式,在main函式裡,執行UIApplicationMain函式;

UIApplicationMain函式會初始化Application物件,並設定一個ApplicationDelegate;

在ApplicationDelegate裡,會通過一些方法去處理系統的一些事件;

UIApplication物件負責接收系統的事件,直到應用程式退出。

注意:UIApplication負責接收系統事件並處理大部分的底層工作,UIApplicationDelegate可以響應一些系統的重要變化(比如狀態的改變、通知的到來等等)

相關文章