你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 淺析UIApplication生命周期的一些delegate方法

淺析UIApplication生命周期的一些delegate方法

編輯:IOS開發基礎

原文

前言

網上有很多關於程序啟動過程和UIApplicationDelegate方法調用順序的文章。筆者這裡不再介紹程序的啟動過程和delegate方法的調用過程。而是介紹一下UIApplication會在什麼情況下調用UIApplicationDelegate的哪些方法。以及常見的場景下,哪些方法會被調用,蘋果為什麼會這樣做。

回顧

首先讓我們先來回顧下與程序啟動過程相關的一些delegate方法的調用時機。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  NSLog(@"程序啟動完成:%s",__func__);
  return YES;
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    NSLog(@"已經獲得焦點:%s",__func__);
}

- (void)applicationWillResignActive:(UIApplication *)application {
    NSLog(@"將要釋放焦點:%s",__func__);
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    NSLog(@"已經進入後台:%s",__func__);
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    NSLog(@"將要進入前台:%s",__func__);
}

- (void)applicationWillTerminate:(UIApplication *)application {
    NSLog(@"程序將要退出:%s",__func__);
}

情景一 程序啟動

程序被加載到內存,完成啟動,application對象會自動調用delegate的下面這個方法,證明程序已經啟動完成。所以這個方法也是首先會被application回調的方法,且這個方法在整個程序的生命周期中只會被調用一次。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

程序啟動時,回調完上面的方法,會繼續回調delegate的已經獲得了焦點的方法,證明程序已經獲得了焦點。

- (void)applicationDidBecomeActive:(UIApplication *)application;

結論:應用啟動過程中,會依次調用delegate已經啟動完成和已經獲得焦點的方法,不會調用已經進入前台的方法。

情景二 程序從前台退出到後台

當程序處於前台時,單擊home鍵,程序會自動退出到後台。在這個過程中,程序會先回調delegate的將要失去焦點的方法,證明程序將要失去焦點。

- (void)applicationWillResignActive:(UIApplication *)application;

調用調用完上面的方法後,程序緊接著會調用delegate已經進入後台的方法,證明程序已經進入後台。

- (void)applicationDidEnterBackground:(UIApplication *)application;

結論:單擊home鍵進入後台會依次調用delegate的將要失去焦點的方法和已經進入後台的方法。

情景三 程序從後台進入到前台

(4)從後台進入前台(無論是雙擊home鍵進入或者點擊應用圖標進入),會回調delegate的將要進入前台方法,證明程序將要進入前台。

- (void)applicationWillEnterForeground:(UIApplication *)application;

回調完上面的方法,緊接著會繼續回調delegate的已經獲得焦點的方法,證明程序已經獲得了焦點。

- (void)applicationDidBecomeActive:(UIApplication *)application;

結論:從後台進入前台,會依次調用delegate的將要進入前台和已經獲得焦點的方法。

情景四 雙擊home鍵切換程序

在前台,雙擊home鍵,只會調用delegate的將要失去焦點的方法,證明程序將要失去焦點。

- (void)applicationWillResignActive:(UIApplication *)application;

當用戶真正切換應用時候,才會繼續調用delegate的已經進入後台的方法,證明程序已經進入後台。

- (void)applicationDidEnterBackground:(UIApplication *)application;

結論:雙擊home鍵切換應用。會分別調用程序將要失去焦點的方法和程序已經進入後台的方法。 且這兩個方法是分開調用的。即,雙擊home鍵時調用將要失去焦點的方法,選擇其他應用時調用已經進入後台的方法。

情景五 在前台雙擊home鍵殺死程序

雙擊home鍵時,只會調用delegate的將要失去焦點的方法(上面已經說過),證明程序將要失去焦點。

- (void)applicationWillResignActive:(UIApplication *)application;

然後手指上滑殺死程序,會直接調用delegate的已經進入後台的方法,證明程序已經進入後台。

- (void)applicationDidEnterBackground:(UIApplication *)application;

然後緊接著調用delegate的程序將要退出的方法,證明程序將要被殺死。

(void)applicationWillTerminate:(UIApplication *)application;

結論:雙擊home鍵然後殺死程序,會按照如下順序調用delegate的方法:

- (void)applicationWillResignActive:(UIApplication *)application;(雙擊home鍵調用)
- (void)applicationDidEnterBackground:(UIApplication *)application;(殺死程序時調用這兩個方法)
- (void)applicationWillTerminate:(UIApplication *)application;

情景六 從其他程序前台雙擊home鍵殺死後台程序

如果從其他程序的前台,雙擊home鍵殺死後台程序,被殺死程序只會回調delegate即將退出的方法。

- (void)applicationWillTerminate:(UIApplication *)application;

為什麼呢?

因為我們是從一個前台程序殺死一個後台程序,這個後台程序當初進入後台時候已經調用了將要釋放焦點和已經進入後台的方法,所以殺死時候只會回調delegate即將終結的方法。

結論:從一個前台程序殺死一個後台程序。後台程序只會回調delegate的程序即將退出的方法。

情景七 下拉通知欄

下拉通知欄,只會回調delegate的程序將要釋放焦點的方法。程序並沒有進入後台,所以不會調用進入後台的方法

- (void)applicationWillResignActive:(UIApplication *)application;

結論:下拉狀態欄只會讓程序失去焦點,並不會讓程序進入後台。

因為下拉通知欄只調用了將要釋放焦點的方法,沒有調用進入後台方法,所以收起通知欄時,只會調用已經獲得焦點的方法,不會調用進入前台的方法。

- (void)applicationDidBecomeActive:(UIApplication *)application;

同樣,從屏幕下方向上滑動屏幕,喚出工具欄時候,也只會調用delegate的將要釋放焦點的方法。收起工具欄時,只會調用delegate的已經獲得焦點的方法。

結論:下拉通知欄或者上拉工具欄,都只是回調delegate的即將釋放焦點的方法,程序不會進入後台。

為什麼

當初學習iOS時候,對這個地方不是很清楚,總是搞不懂為什麼程序的delegate有一個將要進入前台的方法applicationWillEnterForeground:,卻沒有類似於applicationDidEnterForeground:的已經進入前台的方法(純屬捏造)?為什麼程序的delegate有一個已經進入後台的方法applicationDidEnterBackground:卻沒有一個類似於applicationWillEnterBackground:的將要進入後台的方法?為什麼進入前台時,方法的調用順序是applicationWillEnterForeground:和applicationDidBecomeActive:而不是相反?這些問題一直困擾著我。

將要進入前台、已經獲得焦點、將要失去焦點、已經進入後台這幾個方法是比較容易混淆的,且調用順序經常被搞混。但是如果理解了蘋果為什麼這麼設計,這些困惑都將迎刃而解。重點來了:如果一個應用程序失去焦點那麼意味著用戶當前無法進行交互操作,正因如此,程序從前台退出到後台時候,一般會先失去焦點再進入後台避免進入後台過程中用戶還可以和程序進行交互。同理,一個應用程序從後台進入前台也是類似的,會先進入前台再獲得焦點,這樣進入前台過程中未完全准備好的情況下用戶無法操作,保證了程序的安全性。

至於為什麼蘋果沒有提供類似於applicationDidEnterForeground:的已經進入前台的方法,那是因為程序進入前台後必定會回調delegate的已經獲得焦點的方法,所以applicationDidBecomeActive:方法從本質上就相當於我們想象中的applicationDidEnterForeground:,如果我們想要在程序進入前台後做什麼操作,完全可以把這些操作寫到applicationDidBecomeActive:裡。同理,applicationWillResignActive:就相當於我們想象中的applicationWillEnterForeground:。

另外一般如果應用程序要保存用戶數據會在程序將要失去焦點的方法中進行 (而不是在已經進入後台的方法中執行),因為如果用戶雙擊Home不會進入後台只會注銷激活。同理,如果用戶恢復應用狀態一般在已經獲的焦點的方法中執行(而不是在將要進入前台的方法中執行)。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved