application的生命周期

來自CocoaChina?和簡書作者WayneWang的心得體會。

1鹃答、應(yīng)用程序的狀態(tài)

Not running未運行:程序沒啟動乎澄。

Inactive未激活:程序在前臺運行,不過沒有接收到事件测摔。在沒有事件處理情況下程序通常停留在這個狀態(tài)置济。

Active激活:程序在前臺運行而且接收到了事件解恰。這也是前臺的一個正常的模式。

Backgroud后臺:程序在后臺而且能執(zhí)行代碼浙于,大多數(shù)程序進入這個狀態(tài)后會在在這個狀態(tài)上停留一會护盈。時間到之后會進入掛起狀態(tài)(Suspended)。有的程序經(jīng)過特殊的請求后可以長期處于Backgroud狀態(tài)羞酗。

Suspended掛起:程序在后臺不能執(zhí)行代碼腐宋。系統(tǒng)會自動把程序變成這個狀態(tài)而且不會發(fā)出通知。當掛起時檀轨,程序還是停留在內(nèi)存中的胸竞,當系統(tǒng)內(nèi)存低時,系統(tǒng)就把掛起的程序清除掉参萄,為前臺程序提供更多的內(nèi)存卫枝。

2、各個程序運行狀態(tài)時代理的回調(diào)

①告訴代理進程啟動但還沒進入狀態(tài)保存

- (BOOL)application:(UIApplication*)application willFinishLaunchingWithOptions:(NSDictionary*)launchOptions {NSLog(@"①告訴代理進程啟動但還沒進入狀態(tài)保存");returnYES; }

②告訴代理啟動基本完成程序準備開始運行

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {self.window= [[UIWindowalloc] initWithFrame:[[UIScreenmainScreen] bounds]];NSLog(@"②告訴代理啟動基本完成程序準備開始運行");// Override point for customization after application launch.self.window.backgroundColor= [UIColorwhiteColor];? ? [self.windowmakeKeyAndVisible];returnYES; }

其中 launchOptions 是帶有啟動參數(shù)的字典讹挎,存儲有此程序啟動的原因校赤。launchOptions 中的鍵值對可以看UIApplication Class Reference中的 Launch Options Keys 一節(jié)。

若用戶直接啟動淤袜,launchOptions 內(nèi)無數(shù)據(jù);

若由其他應(yīng)用程序通過 openURL: 啟動痒谴,則 UIApplicationLaunchOptionsURLKey 對應(yīng)的對象為啟動 URL(NSURL)衰伯,UIApplicationLaunchOptionsSourceApplicationKey 對應(yīng)啟動的源應(yīng)用程序的bundle ID (NSString)铡羡;

若由本地通知啟動,則 UIApplicationLaunchOptionsLocalNotificationKey 對應(yīng)的是為啟動應(yīng)用程序的的本地通知對象(UILocalNotification)意鲸;

若由遠程通知啟動,則 UIApplicationLaunchOptionsRemoteNotificationKey 對應(yīng)的是啟動應(yīng)用程序的的遠程通知信息 userInfo(NSDictionary)怎顾;

其他key還有 UIApplicationLaunchOptionsAnnotationKey读慎、UIApplicationLaunchOptionsLocationKey、

UIApplicationLaunchOptionsNewsstandDownloadsKey槐雾。

如果要在啟動時夭委,做出一些區(qū)分,那就需要在下面的代碼做處理募强。

比如應(yīng)用可以被某個其它應(yīng)用調(diào)起株灸,那可能要在啟動代碼的地方做出一些驗證,比如以下例子擎值。

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {NSURL*url = [options objectForKey:UIApplicationLaunchOptionsURLKey];if(url) {// do something.}NSString*bundleId = [options objectForKey:UIApplicationLaunchOptionsSourceApplicationKey];if(bundleId) {// do something.}UILocalNotification* localNotify = [options objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];if(localNotify) {// do something.}NSDictionary* userInfo = [options objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];if(userInfo) {// do something.}}

③當應(yīng)用程序?qū)⒁敕腔顒訝顟B(tài)執(zhí)行慌烧,在此期間,應(yīng)用程序不接收消息或事件鸠儿,比如來電話

- (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.NSLog(@"③當應(yīng)用程序?qū)⒁敕腔顒訝顟B(tài)執(zhí)行屹蚊,在此期間厕氨,應(yīng)用程序不接收消息或事件,比如來電話"); }

④當應(yīng)用程序進入活動狀態(tài)執(zhí)行

- (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.NSLog(@"④當應(yīng)用程序進入活動狀態(tài)執(zhí)行"); }

⑤當程序被推送到后臺的時候調(diào)用汹粤。所以要設(shè)置后臺繼續(xù)運行命斧,則在這個函數(shù)里面設(shè)置即可

- (void)applicationDidEnterBackground:(UIApplication *)application {? ? //Usethis methodtoreleasesharedresources,saveuserdata,invalidatetimers,andstoreenough application state informationtorestoreyour applicationtoitscurrentstateincaseitisterminatedlater.? ? //Ifyour application supports background execution, this methodiscalled insteadofapplicationWillTerminate:whentheuserquits.? ? NSLog(@"⑤當程序被推送到后臺的時候調(diào)用");[application beginBackgroundTaskWithExpirationHandler:^{? ? ? ? NSLog(@"beginBackground TaskWithExpirationHandler");

}];

}

⑥當程序從后臺將要重新回到前臺時候調(diào)用

- (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(@"⑥當程序從后臺將要重新回到前臺時候調(diào)用");? }

⑦當程序?qū)⒁顺鍪潜徽{(diào)用,通常是用來保存數(shù)據(jù)和一些退出前的清理工作嘱兼。這個需要要設(shè)置UIApplicationExitsOnSuspend的鍵值

- (void)applicationWillTerminate:(UIApplication*)application {// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.NSLog(@"⑦當程序?qū)⒁顺鍪潜徽{(diào)用");? }

⑧當程序載入后執(zhí)行

-(void)applicationDidFinishLaunching:(UIApplication *)application {NSLog(@"⑧當程序載入后執(zhí)行");? }

程序啟動時:

2014-07-01 15:55:14.706 LifeCycle[5845:60b] ①告訴代理進程啟動但還沒進入狀態(tài)保存

2014-07-01 15:55:14.708 LifeCycle[5845:60b] ②告訴代理啟動基本完成程序準備開始運行

2014-07-01 15:55:14.709 LifeCycle[5845:60b] ④當應(yīng)用程序進入活動狀態(tài)執(zhí)行

按下Home鍵返回主界面:

2014-07-01 15:56:11.756 LifeCycle[5845:60b] ③當應(yīng)用程序?qū)⒁敕腔顒訝顟B(tài)執(zhí)行

2014-07-01 15:56:11.814 LifeCycle[5845:60b] ⑤當程序被推送到后臺的時候調(diào)用

再次打開程序:

2014-07-01 15:57:19.200 LifeCycle[5845:60b] ⑥當程序從后臺將要重新回到前臺時候調(diào)用

2014-07-01 15:57:19.201 LifeCycle[5845:60b] ④當應(yīng)用程序進入活動狀態(tài)執(zhí)行

3冯丙、加載應(yīng)用程序進入前臺

4、加載應(yīng)用程序進入后臺

5遭京、基于警告式響應(yīng)中斷

當出現(xiàn)這種中斷時胃惜,我們需要在- (void)applicationWillResignActive:(UIApplication *)application方法中進行如下操作:

①停止timer 和其他周期性的任務(wù)

②停止任何正在運行的請求

③暫停視頻的播放

④如果是游戲那就暫停它

⑤減少OpenGL ES的幀率

⑥掛起任何分發(fā)的隊列和不重要的操作隊列(你可以繼續(xù)處理網(wǎng)絡(luò)請求或其他時間敏感的后臺任務(wù))

當程序回到active狀態(tài),我們需要在- (void)applicationDidBecomeActive:(UIApplication *)application方法中重新開始上述任務(wù)哪雕。不過游戲要回到暫停狀態(tài)船殉,不能自動開始。

6斯嚎、進入后臺運行

當應(yīng)用程序進入后臺時利虫,我們應(yīng)該做些什么?

保存用戶數(shù)據(jù)或狀態(tài)信息堡僻,所有沒寫到磁盤的文件或信息糠惫,在進入后臺時,最后都寫到磁盤去钉疫,因為程序可能在后臺被殺死硼讽。

釋放盡可能釋放的內(nèi)存。

- (void)applicationDidEnterBackground:(UIApplication*)application

方法有大概5秒的時間讓你完成這些任務(wù)牲阁。如果超過時間還有未完成的任務(wù)固阁,你的程序就會被終止而且從內(nèi)存中清除。

如果還需要長時間的運行任務(wù)城菊,可以在該方法中調(diào)用

[applicationbeginBackgroundTaskWithExpirationHandler:^{? ? NSLog(@"begin Background Task With Expiration Handler");}];

應(yīng)用程序在后臺時的內(nèi)存使用:請求后臺運行時間和啟動線程來運行長時間運行的任務(wù)备燃。

在后臺時,每個應(yīng)用程序都應(yīng)該釋放最大的內(nèi)存凌唬。系統(tǒng)努力的保持更多的應(yīng)用程序在后臺同時 運行并齐。不過當內(nèi)存不足時,會終止一些掛起的程序來回收內(nèi)存客税,那些內(nèi)存最大的程序首先被終止况褪。

事實上,應(yīng)用程序應(yīng)該的對象如果不再使用了霎挟,那就應(yīng)該盡快的去掉強引用窝剖,這樣編譯器可以回收這些內(nèi)存。如果你想緩存一些對象提升程序的性能酥夭,你可以在進入后臺時赐纱,把這些對象去掉強引用脊奋。

下面這樣的對象應(yīng)該盡快的去掉強引用:

①圖片對象

②你可以重新加載的 大的視頻或數(shù)據(jù)文件

③任何沒用而且可以輕易創(chuàng)建的對象

在后臺時,為了減少程序占用的內(nèi)存疙描,系統(tǒng)會自動在回收一些系統(tǒng)幫助你開辟的內(nèi)存诚隙。比如:

①系統(tǒng)回收Core Animation的后備存儲。

②去掉任何系統(tǒng)引用的緩存圖片

③去掉系統(tǒng)管理數(shù)據(jù)緩存強引用

7起胰、返回前臺運行

在暫停狀態(tài)的應(yīng)用程序必須準備處理任何排隊的通知時久又,它返回到前臺或后臺執(zhí)行狀態(tài)。暫停的應(yīng)用程序不執(zhí)行任何代碼效五,因此不能處理與方向的變化地消,時間的變化,偏好的變化畏妖,以及許多其他會影響應(yīng)用程序的外觀或狀態(tài)的通知脉执。為了確保這些更改不會丟失,系統(tǒng)排隊許多相關(guān)的通知戒劫,并把它們傳遞給應(yīng)用程序半夷,只要它開始再次執(zhí)行代碼(無論是在前景或背景)。為了防止由偏快轉(zhuǎn)為超載與它恢復(fù)時通知您的應(yīng)用程序迅细,該系統(tǒng)凝聚事件巫橄,并提供一個單一的通知(每個相關(guān)類型),反映了凈變化茵典,因為你的應(yīng)用程序被暫停湘换。

8、程序終止

程序只要符合以下情況之一敬尺,只要進入后臺或掛起狀態(tài)就會終止:

①iOS4.0以前的系統(tǒng)

②app是基于iOS4.0之前系統(tǒng)開發(fā)的枚尼。

③設(shè)備不支持多任務(wù)

④在Info.plist文件中,程序包含了 UIApplicationExitsOnSuspend? 鍵砂吞。

app如果終止了,系統(tǒng)會調(diào)用app的代理的方法 - (void)applicationWillTerminate:(UIApplication *)application崎溃,這樣可以讓你可以做一些清理工作蜻直。你可以保存一些數(shù)據(jù)或app的狀態(tài)。這個方法也有5秒鐘的限制袁串。超時后方法會返回程序從內(nèi)存中清除概而。

注意:用戶可以手工關(guān)閉應(yīng)用程序。

9囱修、The Main Run Loop? 主運行循環(huán)

Main Run Loop負責(zé)處理用戶相關(guān)的事件赎瑰。UIApplication對象在程序啟動時啟動main run Loop,它處理事件和更新視圖的界面破镰〔吐看Main Run Loop就知道压储,它是運行在程序的主線程上的。這樣保證了接收到用戶相關(guān)操作的事件是按順序處理的源譬。

用戶操作設(shè)備集惋,相關(guān)的操作事件被系統(tǒng)生成并通過UIKit的指定端口分發(fā)。事件在內(nèi)部排成隊列踩娘,一個個的分發(fā)到Main run loop 去做處理刮刑。UIApplication對象是第一個接收到時間的對象,它決定事件如何被處理养渴。觸摸事件分發(fā)到主窗口雷绢,窗口再分發(fā)到對應(yīng)出發(fā)觸摸事件的View。其他的事件通過其他途徑分發(fā)給其他對象變量做處理理卑。

大部分的事件可以在你的應(yīng)用里分發(fā)习寸,類似于觸摸事件,遠程操控事件(線控耳機等)都是由app的 responder objects 對象處理的傻工。Responder objects 在你的app里到處都是霞溪,比如:UIApplication 對象,view對象中捆,view controller 對象鸯匹,都是resopnder objects秆剪。大部分事件的目標都指定了resopnder object嫂沉,不過事件也可以傳遞給其他對象。比如狂窑,如果view對象不處理事件蟋滴,可以傳給父類view或者view controller染厅。

文/WayneWang(簡書作者)

原文鏈接:http://www.reibang.com/p/9f2c7e80b84b

著作權(quán)歸作者所有,轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)津函,并標注“簡書作者”肖粮。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市尔苦,隨后出現(xiàn)的幾起案子涩馆,更是在濱河造成了極大的恐慌,老刑警劉巖允坚,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件魂那,死亡現(xiàn)場離奇詭異,居然都是意外死亡稠项,警方通過查閱死者的電腦和手機涯雅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來展运,“玉大人活逆,你說我怎么就攤上這事精刷。” “怎么了划乖?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵贬养,是天一觀的道長。 經(jīng)常有香客問我琴庵,道長误算,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任迷殿,我火速辦了婚禮儿礼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘庆寺。我一直安慰自己蚊夫,他們只是感情好,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布懦尝。 她就那樣靜靜地躺著知纷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪陵霉。 梳的紋絲不亂的頭發(fā)上琅轧,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音踊挠,去河邊找鬼乍桂。 笑死,一個胖子當著我的面吹牛效床,可吹牛的內(nèi)容都是我干的睹酌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼剩檀,長吁一口氣:“原來是場噩夢啊……” “哼憋沿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谨朝,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤卤妒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后字币,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡共缕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年洗出,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片图谷。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡翩活,死狀恐怖阱洪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情菠镇,我是刑警寧澤冗荸,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站利耍,受9級特大地震影響蚌本,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜隘梨,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一程癌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧轴猎,春花似錦嵌莉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至可婶,卻和暖如春沿癞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扰肌。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工抛寝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人曙旭。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓盗舰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親桂躏。 傳聞我的和親對象是個殘疾皇子钻趋,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

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