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

前言

網(wǎng)上有很多關(guān)于程序啟動(dòng)過程和UIApplicationDelegate方法調(diào)用順序的文章膏秫。筆者這里不再介紹程序的啟動(dòng)過程和delegate方法的調(diào)用過程白华。而是介紹一下UIApplication會(huì)在什么情況下調(diào)用UIApplicationDelegate的哪些方法屯烦。以及常見的場景下凉当,哪些方法會(huì)被調(diào)用茄靠,蘋果為什么會(huì)這樣做璧榄。

回顧

首先讓我們先來回顧下與程序啟動(dòng)過程相關(guān)的一些delegate方法的調(diào)用時(shí)機(jī)特漩。

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

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

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

- (void)applicationDidEnterBackground:(UIApplication *)application {
    NSLog(@"已經(jīng)進(jìn)入后臺(tái):%s",__func__);
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    NSLog(@"將要進(jìn)入前臺(tái):%s",__func__);
}

- (void)applicationWillTerminate:(UIApplication *)application {
    NSLog(@"程序?qū)⒁顺觯?s",__func__);
}

情景一 程序啟動(dòng)

程序被加載到內(nèi)存,完成啟動(dòng)骨杂,application對(duì)象會(huì)自動(dòng)調(diào)用delegate的下面這個(gè)方法涂身,證明程序已經(jīng)啟動(dòng)完成。所以這個(gè)方法也是首先會(huì)被application回調(diào)的方法搓蚪,且這個(gè)方法在整個(gè)程序的生命周期中只會(huì)被調(diào)用一次蛤售。

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

程序啟動(dòng)時(shí),回調(diào)完上面的方法妒潭,會(huì)繼續(xù)回調(diào)delegate的已經(jīng)獲得了焦點(diǎn)的方法悴能,證明程序已經(jīng)獲得了焦點(diǎn)

- (void)applicationDidBecomeActive:(UIApplication *)application雳灾;
```

>結(jié)論:應(yīng)用啟動(dòng)過程中漠酿,會(huì)依次調(diào)用delegate已經(jīng)啟動(dòng)完成和已經(jīng)獲得焦點(diǎn)的方法,不會(huì)調(diào)用已經(jīng)進(jìn)入前臺(tái)的方法谎亩。

#### 情景二  程序從前臺(tái)退出到后臺(tái)
當(dāng)程序處于前臺(tái)時(shí),單擊home鍵炒嘲,程序會(huì)自動(dòng)退出到后臺(tái)。在這個(gè)過程中匈庭,程序會(huì)先回調(diào)delegate的將要失去焦點(diǎn)的方法夫凸,證明程序**`將要失去焦點(diǎn)`**。
```
- (void)applicationWillResignActive:(UIApplication *)application;
```

調(diào)用調(diào)用完上面的方法后阱持,程序緊接著會(huì)調(diào)用delegate已經(jīng)進(jìn)入后臺(tái)的方法夭拌,證明**`程序已經(jīng)進(jìn)入后臺(tái)`**。
```
- (void)applicationDidEnterBackground:(UIApplication *)application;
```

> 結(jié)論:單擊home鍵進(jìn)入后臺(tái)會(huì)依次調(diào)用delegate的將要失去焦點(diǎn)的方法和已經(jīng)進(jìn)入后臺(tái)的方法衷咽。

####情景三  程序從后臺(tái)進(jìn)入到前臺(tái)
(4)從后臺(tái)進(jìn)入前臺(tái)(無論是雙擊home鍵進(jìn)入或者點(diǎn)擊應(yīng)用圖標(biāo)進(jìn)入)鸽扁,會(huì)回調(diào)delegate的將要進(jìn)入前臺(tái)方法,證明**`程序?qū)⒁M(jìn)入前臺(tái)`**镶骗。
```
- (void)applicationWillEnterForeground:(UIApplication *)application;
```

回調(diào)完上面的方法桶现,緊接著會(huì)繼續(xù)回調(diào)delegate的已經(jīng)獲得焦點(diǎn)的方法,證明程序**`已經(jīng)獲得了焦點(diǎn)`**卖词。
```
- (void)applicationDidBecomeActive:(UIApplication *)application;
```

> 結(jié)論:從后臺(tái)進(jìn)入前臺(tái),會(huì)依次調(diào)用delegate的將要進(jìn)入前臺(tái)和已經(jīng)獲得焦點(diǎn)的方法此蜈。


#### 情景四  雙擊home鍵切換程序
在前臺(tái)即横,雙擊home鍵,只會(huì)調(diào)用delegate的將要失去焦點(diǎn)的方法裆赵,證明```程序?qū)⒁ソ裹c(diǎn)```东囚。
```
- (void)applicationWillResignActive:(UIApplication *)application;
```


當(dāng)用戶真正切換應(yīng)用時(shí)候,才會(huì)繼續(xù)調(diào)用delegate的已經(jīng)進(jìn)入后臺(tái)的方法战授,證明**`程序已經(jīng)進(jìn)入后臺(tái)`**页藻。

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

> 結(jié)論:雙擊home鍵切換應(yīng)用。會(huì)分別調(diào)用程序?qū)⒁ソ裹c(diǎn)的方法和程序已經(jīng)進(jìn)入后臺(tái)的方法植兰。 且這兩個(gè)方法是分開調(diào)用的份帐。即,雙擊home鍵時(shí)調(diào)用將要失去焦點(diǎn)的方法楣导,選擇其他應(yīng)用時(shí)調(diào)用已經(jīng)進(jìn)入后臺(tái)的方法废境。

####情景五 在前臺(tái)雙擊home鍵殺死程序

雙擊home鍵時(shí),只會(huì)調(diào)用delegate的將要失去焦點(diǎn)的方法(上面已經(jīng)說過),證明程序?qū)⒁ソ裹c(diǎn)筒繁。
```
- (void)applicationWillResignActive:(UIApplication *)application;
```


然后手指上滑殺死程序噩凹,會(huì)直接調(diào)用delegate的已經(jīng)進(jìn)入后臺(tái)的方法,證明程序已經(jīng)進(jìn)入后臺(tái)毡咏。
```
- (void)applicationDidEnterBackground:(UIApplication *)application;
```
然后緊接著調(diào)用delegate的程序?qū)⒁顺龅姆椒ㄍ匝纾C明程序?qū)⒁粴⑺馈?- (void)applicationWillTerminate:(UIApplication *)application;

> 結(jié)論:雙擊home鍵然后殺死程序,會(huì)按照如下順序調(diào)用delegate的方法:
```
- (void)applicationWillResignActive:(UIApplication *)application;(雙擊home鍵調(diào)用)
```
```
- (void)applicationDidEnterBackground:(UIApplication *)application;(殺死程序時(shí)調(diào)用這兩個(gè)方法)
- (void)applicationWillTerminate:(UIApplication *)application;
```

####情景六 從其他程序前臺(tái)雙擊home鍵殺死后臺(tái)程序

如果從其他程序的前臺(tái)呕缭,雙擊home鍵殺死后臺(tái)程序堵泽,被殺死程序只會(huì)回調(diào)delegate即將退出的方法。
```
- (void)applicationWillTerminate:(UIApplication *)application;
```

**為什么呢臊旭?**
因?yàn)槲覀兪菑囊粋€(gè)前臺(tái)程序殺死一個(gè)后臺(tái)程序落恼,這個(gè)后臺(tái)程序當(dāng)初進(jìn)入后臺(tái)時(shí)候已經(jīng)調(diào)用了將要釋放焦點(diǎn)和已經(jīng)進(jìn)入后臺(tái)的方法,所以殺死時(shí)候只會(huì)回調(diào)delegate即將終結(jié)的方法离熏。

> 結(jié)論:從一個(gè)前臺(tái)程序殺死一個(gè)后臺(tái)程序佳谦。后臺(tái)程序只會(huì)回調(diào)delegate的程序即將退出的方法。

---

####情景七 下拉通知欄
下拉通知欄滋戳,只會(huì)回調(diào)delegate的程序?qū)⒁尫沤裹c(diǎn)的方法钻蔑。程序并沒有進(jìn)入后臺(tái),所以不會(huì)調(diào)用進(jìn)入后臺(tái)的方法
```
- (void)applicationWillResignActive:(UIApplication *)application;
```

結(jié)論:下拉狀態(tài)欄只會(huì)讓程序失去焦點(diǎn)奸鸯,并不會(huì)讓程序進(jìn)入后臺(tái)咪笑。

因?yàn)橄吕ㄖ獧谥徽{(diào)用了將要釋放焦點(diǎn)的方法,沒有調(diào)用進(jìn)入后臺(tái)方法娄涩,所以收起通知欄時(shí)窗怒,只會(huì)調(diào)用已經(jīng)獲得焦點(diǎn)的方法映跟,不會(huì)調(diào)用進(jìn)入前臺(tái)的方法。
```
- (void)applicationDidBecomeActive:(UIApplication *)application扬虚;
```

同樣努隙,從屏幕下方向上滑動(dòng)屏幕,喚出工具欄時(shí)候辜昵,也只會(huì)調(diào)用delegate的將要釋放焦點(diǎn)的方法荸镊。收起工具欄時(shí),只會(huì)調(diào)用delegate的已經(jīng)獲得焦點(diǎn)的方法堪置。

> 結(jié)論:下拉通知欄或者上拉工具欄躬存,都只是回調(diào)delegate的即將釋放焦點(diǎn)的方法,程序不會(huì)進(jìn)入后臺(tái)舀锨。

## 為什么
當(dāng)初學(xué)習(xí)iOS時(shí)候岭洲,對(duì)這個(gè)地方不是很清楚,總是搞不懂為什么程序的delegate有一個(gè)將要進(jìn)入前臺(tái)的方法`applicationWillEnterForeground:`雁竞,卻沒有類似于`applicationDidEnterForeground:`的已經(jīng)進(jìn)入前臺(tái)的方法(純屬捏造)钦椭?為什么程序的delegate有一個(gè)已經(jīng)進(jìn)入后臺(tái)的方法`applicationDidEnterBackground:`卻沒有一個(gè)類似于`applicationWillEnterBackground:`的將要進(jìn)入后臺(tái)的方法?為什么進(jìn)入前臺(tái)時(shí)碑诉,方法的調(diào)用順序是`applicationWillEnterForeground:`和`applicationDidBecomeActive:`而不是相反彪腔?這些問題一直困擾著我。

**將要進(jìn)入前臺(tái)进栽、已經(jīng)獲得焦點(diǎn)德挣、將要失去焦點(diǎn)、已經(jīng)進(jìn)入后臺(tái)**這幾個(gè)方法是比較容易混淆的快毛,且調(diào)用順序經(jīng)常被搞混格嗅。但是如果理解了蘋果為什么這么設(shè)計(jì),這些困惑都將迎刃而解唠帝。重點(diǎn)來了:如果一個(gè)應(yīng)用程序失去焦點(diǎn)那么意味著用戶當(dāng)前無法進(jìn)行交互操作屯掖,正因如此,程序從前臺(tái)退出到后臺(tái)時(shí)候襟衰,一般會(huì)**先失去焦點(diǎn)再進(jìn)入后臺(tái)**避免進(jìn)入后臺(tái)過程中用戶還可以和程序進(jìn)行交互贴铜。同理,一個(gè)應(yīng)用程序從后臺(tái)進(jìn)入前臺(tái)也是類似的瀑晒,會(huì)**先進(jìn)入前臺(tái)再獲得焦點(diǎn)**绍坝,這樣進(jìn)入前臺(tái)過程中未完全準(zhǔn)備好的情況下用戶無法操作,保證了程序的安全性苔悦。
至于為什么蘋果沒有提供類似于`applicationDidEnterForeground:`的已經(jīng)進(jìn)入前臺(tái)的方法轩褐,那是因?yàn)槌绦蜻M(jìn)入前臺(tái)后必定會(huì)回調(diào)delegate的已經(jīng)獲得焦點(diǎn)的方法,所以`applicationDidBecomeActive:`方法從本質(zhì)上就相當(dāng)于我們想象中的`applicationDidEnterForeground:`玖详,如果我們想要在程序進(jìn)入前臺(tái)后做什么操作把介,完全可以把這些操作寫到`applicationDidBecomeActive:`里勤讽。同理,`applicationWillResignActive:`就相當(dāng)于我們想象中的`applicationWillEnterForeground:`拗踢。

另外一般如果**應(yīng)用程序要保存用戶數(shù)據(jù)會(huì)在程序?qū)⒁ソ裹c(diǎn)的方法中進(jìn)行 (而不是在已經(jīng)進(jìn)入后臺(tái)的方法中執(zhí)行)**地技,因?yàn)槿绻脩綦p擊Home不會(huì)進(jìn)入后臺(tái)只會(huì)注銷激活。同理秒拔,如果用戶恢復(fù)應(yīng)用狀態(tài)一般在已經(jīng)獲的焦點(diǎn)的方法中執(zhí)行(而不是在將要進(jìn)入前臺(tái)的方法中執(zhí)行)。

  文/VV木公子(簡書作者)
**PS:如非特別說明飒硅,所有文章均為原創(chuàng)作品砂缩,著作權(quán)歸作者所有,轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)三娩,并注明出處庵芭,所有打賞均歸本人所有!**

如果您是iOS開發(fā)者雀监,或者對(duì)本篇文章感興趣双吆,請關(guān)注本人,后續(xù)會(huì)更新更多相關(guān)文章会前!敬請期待好乐!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市瓦宜,隨后出現(xiàn)的幾起案子蔚万,更是在濱河造成了極大的恐慌,老刑警劉巖临庇,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件反璃,死亡現(xiàn)場離奇詭異,居然都是意外死亡假夺,警方通過查閱死者的電腦和手機(jī)淮蜈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來已卷,“玉大人梧田,你說我怎么就攤上這事〉课玻” “怎么了柿扣?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長闺魏。 經(jīng)常有香客問我未状,道長,這世上最難降的妖魔是什么析桥? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任司草,我火速辦了婚禮艰垂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘埋虹。我一直安慰自己猜憎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布搔课。 她就那樣靜靜地躺著胰柑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪爬泥。 梳的紋絲不亂的頭發(fā)上柬讨,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音袍啡,去河邊找鬼踩官。 笑死,一個(gè)胖子當(dāng)著我的面吹牛境输,可吹牛的內(nèi)容都是我干的蔗牡。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼嗅剖,長吁一口氣:“原來是場噩夢啊……” “哼辩越!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起信粮,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤区匣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蒋院,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體亏钩,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年欺旧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了姑丑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辞友,死狀恐怖栅哀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情称龙,我是刑警寧澤留拾,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站鲫尊,受9級(jí)特大地震影響痴柔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜疫向,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一咳蔚、第九天 我趴在偏房一處隱蔽的房頂上張望豪嚎。 院中可真熱鬧,春花似錦谈火、人聲如沸侈询。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扔字。三九已至,卻和暖如春温技,著一層夾襖步出監(jiān)牢的瞬間啦租,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來泰國打工荒揣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人焊刹。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓系任,卻偏偏與公主長得像,于是被迫代替她去往敵國和親虐块。 傳聞我的和親對(duì)象是個(gè)殘疾皇子俩滥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容