處理應(yīng)用程序狀態(tài)轉(zhuǎn)換的策略
對于應(yīng)用程序的每個可能的運行時狀態(tài),系統(tǒng)在您的應(yīng)用程序處于該狀態(tài)時具有不同的期望值。當(dāng)狀態(tài)轉(zhuǎn)換發(fā)生時,系統(tǒng)會通知應(yīng)用對象,該對象又通知其應(yīng)用代理。您可以使用UIApplicationDelegate協(xié)議的狀態(tài)轉(zhuǎn)換方法來檢測這些狀態(tài)變化并進行適當(dāng)?shù)捻憫?yīng)。例如,當(dāng)從前臺轉(zhuǎn)移到后臺時,您可能會寫出任何未保存的數(shù)據(jù),并停止任何正在進行的任務(wù)。以下部分提供了有關(guān)如何實現(xiàn)狀態(tài)轉(zhuǎn)換代碼的提示和指導(dǎo)。
在啟動時怎么辦
當(dāng)您的應(yīng)用程序啟動(前進或后臺)時,請使用應(yīng)用程序委托應(yīng)用程序:willFinishLaunchingWithOptions:和application:didFinishLaunchingWithOptions:執(zhí)行以下操作的方法:
檢查啟動選項字典的內(nèi)容,了解應(yīng)用程序啟動的原因,并進行適當(dāng)?shù)捻憫?yīng)。
初始化您的應(yīng)用程序的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)。
準備您的應(yīng)用程序的窗口和視圖進行顯示:
使用OpenGL ES進行繪圖的應(yīng)用程序不得使用這些方法來準備繪圖環(huán)境。相反,將任何OpenGLES繪圖調(diào)用延遲到applicationDidBecomeActive:方法。
從您的應(yīng)用程序顯示您的應(yīng)用程序窗口:willFinishLaunchingWithOptions:method。UIKit延遲使窗口可見,直到應(yīng)用程序之后:didFinishLaunchingWithOptions:method返回。
在啟動時,系統(tǒng)自動加載應(yīng)用程序的主要故事板文件,并加載初始視圖控制器。對于支持狀態(tài)恢復(fù)的應(yīng)用程序,狀態(tài)恢復(fù)機制將您的界面恢復(fù)到對應(yīng)用程序的調(diào)用之前的狀態(tài):willFinishLaunchingWithOptions:andapplication:didFinishLaunchingWithOptions:methods。使用應(yīng)用程序:willFinishLaunchingWithOptions:方法顯示您的應(yīng)用程序窗口,并確定狀態(tài)恢復(fù)是否應(yīng)該發(fā)生。使用應(yīng)用程序:didFinishLaunchingWithOptions:方法對應(yīng)用程序的用戶界面進行任何最終調(diào)整。
您的應(yīng)用程序:willFinishLaunchingWithOptions:和應(yīng)用程序:didFinishLaunchingWithOptions:方法應(yīng)始終盡可能輕量級,以減少您的應(yīng)用程序的啟動時間。應(yīng)用程序預(yù)計將啟動,初始化自己,并在不到5秒鐘內(nèi)開始處理事件。如果應(yīng)用程序沒有及時完成其啟動周期,系統(tǒng)將使其無法響應(yīng)。因此,任何可能減慢啟動速度(例如訪問網(wǎng)絡(luò))的任務(wù)都應(yīng)該在輔助線程上執(zhí)行。
啟動周期
當(dāng)您的應(yīng)用程序啟動時,它將從非運行狀態(tài)移動到活動狀態(tài)或背景狀態(tài),暫時轉(zhuǎn)換到非活動狀態(tài)。作為啟動周期的一部分,系統(tǒng)為您的應(yīng)用程序創(chuàng)建一個進程和主線程,并在該主線程上調(diào)用您的應(yīng)用程序的主要功能。您的Xcode項目隨附的默認主要功能可以手動控制到UIKit框架,這在大多數(shù)工作中初始化您的應(yīng)用程序并準備運行。
圖4-1顯示應(yīng)用程序啟動到前臺時發(fā)生的事件序列,包括調(diào)用的應(yīng)用程序代理方法。

圖4-1將應(yīng)用程序啟動到前臺
當(dāng)您的應(yīng)用程序啟動到后臺時 - 通常來處理某些類型的背景事件 - 啟動周期會略有變化,如圖4-2所示。主要區(qū)別在于,您的應(yīng)用程式不是活躍的,而是進入后臺狀態(tài)來處理該事件,之后可能會被暫停。 當(dāng)啟動到后臺時,系統(tǒng)仍然會加載您的應(yīng)用程序的用戶界面文件,但不會顯示應(yīng)用程序的窗口。

圖4-2將應(yīng)用程序啟動到后臺
要確定您的應(yīng)用程序是啟動到前臺還是后臺,請檢查應(yīng)用程序中共享的UIApplication對象的applicationState屬性:willFinishLaunchingWithOptions:或application:didFinishLaunchingWithOptions:delegate方法。當(dāng)應(yīng)用程序啟動到前臺時,此屬性包含值UIApplicationStateInactive。當(dāng)應(yīng)用程序啟動到后臺時,該屬性包含值UIApplicationStateBackground。您可以使用此差異來相應(yīng)地調(diào)整委托方法的啟動時間行為。
注意:啟動應(yīng)用程序以便可以打開URL時,啟動事件的順序與圖4-1和圖4-2所示的順序不同。有關(guān)打開URL時啟動序列的信息,請參閱處理URL請求。Handling URL Requests
以橫向模式啟動
僅使用其界面的橫向應(yīng)用程序的應(yīng)用程序必須明確要求系統(tǒng)以該方向啟動應(yīng)用程序。通常,應(yīng)用程序以縱向模式啟動,并根據(jù)需要旋轉(zhuǎn)其界面以匹配設(shè)備方向。對于支持縱向和橫向方向的應(yīng)用程序,請始終為縱向模式配置視圖,然后讓視圖控制器處理任何旋轉(zhuǎn)。但是,如果您的應(yīng)用程序支持橫向,但不支持縱向方向,請執(zhí)行以下任務(wù),以使其以橫向模式啟動:
將UIInterfaceOrientation鍵添加到應(yīng)用程序的Info.plist文件中,并將該鍵的值設(shè)置為UIInterfaceOrientationLandscapeLeft或UIInterfaceOrientationLandscapeRight。
在橫向模式下放置視圖,并確保其布局或自動調(diào)整選項設(shè)置正確。
覆蓋您的視圖控制器的shouldAotorotateToInterfaceOrientation:方法,并為左側(cè)或右側(cè)橫向方向返回YES,然后為縱向方向返回NO。
重要提示:應(yīng)用程序應(yīng)始終使用視圖控制器來管理其基于窗口的內(nèi)容。
Info.plist文件中的UIInterfaceOrientation鍵告訴iOS應(yīng)該配置應(yīng)用狀態(tài)欄的方向(如果顯示)以及任何視圖控制器在啟動時管理的視圖的方向。視圖控制器尊重此鍵并設(shè)置其視圖的初始方向進行匹配。使用此鍵相當(dāng)于在執(zhí)行您的applicationDidFinishLaunching:方法時調(diào)用setStatusBarOrientation:animated:UIApplication方法。
首次啟動時安裝應(yīng)用專用數(shù)據(jù)文件
您可以使用應(yīng)用程序的第一個啟動周期來設(shè)置運行所需的任何數(shù)據(jù)或配置文件。應(yīng)用程序特定的數(shù)據(jù)文件應(yīng)在應(yīng)用程序沙箱的庫/應(yīng)用程序支持/ /目錄中創(chuàng)建,其中是應(yīng)用程序的捆綁標識符。您可以根據(jù)需要進一步細分此目錄來組織數(shù)據(jù)文件。您還可以根據(jù)需要在其他目錄中創(chuàng)建文件,如應(yīng)用程序的iCloud容器目錄或本地Documents目錄。
如果您的應(yīng)用程序包包含您打算修改的數(shù)據(jù)文件,請將這些文件從應(yīng)用程序包中復(fù)制出來并修改副本。您不得修改應(yīng)用程序包內(nèi)的任何文件。由于iOS應(yīng)用程式是代碼簽名的,因此修改應(yīng)用程式包中的檔案會使應(yīng)用程式的簽名無效,并將阻止您的應(yīng)用程式在將來啟動。將這些文件復(fù)制到應(yīng)用程序支持目錄(或沙箱中的另一個可寫目錄),并將其修改為安全使用這些文件的唯一方法。
有關(guān)放置應(yīng)用程序相關(guān)數(shù)據(jù)文件的位置的更多信息,請參閱“文件系統(tǒng)編程指南”。File System Programming Guide.
當(dāng)你的應(yīng)用程序暫時中斷時該怎么辦
基于警報的中斷導(dǎo)致您的應(yīng)用程序暫時失去控制權(quán)。您的應(yīng)用程序繼續(xù)在前臺運行,但不會從系統(tǒng)接收到觸摸事件。(它確實繼續(xù)接收通知和其他類型的事件,例如加速度計事件。)為了響應(yīng)此更改,您的應(yīng)用程序應(yīng)在其ApplicationWillResignActive:方法中執(zhí)行以下操作:
保存數(shù)據(jù)和任何相關(guān)狀態(tài)信息。
停止計時器和其他定期任務(wù)。
停止任何運行的元數(shù)據(jù)查詢
不要啟動任何新任務(wù)。
暫停播放電影(在AirPlay上播放時除外)。
如果您的應(yīng)用是游戲,請進入暫停狀態(tài)。
打開OpenGL ES幀速率。
暫停執(zhí)行非關(guān)鍵代碼的任何調(diào)度隊列或運行隊列。 (您可以在不活動的情況下繼續(xù)處理網(wǎng)絡(luò)請求和其他時間敏感的后臺任務(wù)。)
當(dāng)您的應(yīng)用程序移回到活動狀態(tài)時,其applicationDidBecomeActive:方法應(yīng)該可以扭轉(zhuǎn)applicationWillResignActive:方法中執(zhí)行的任何步驟。因此,重新啟動后,您的應(yīng)用程序應(yīng)重新啟動計時器,恢復(fù)調(diào)度隊列,并再次調(diào)低OpenGLES幀速率。但是,游戲不應(yīng)該自動恢復(fù);它們應(yīng)該保持暫停,直到用戶選擇恢復(fù)它們?yōu)橹埂?/p>
當(dāng)用戶按下睡眠/喚醒按鈕時,具有受NSFileProtectionComplete保護選項保護的文件的應(yīng)用程序必須關(guān)閉對這些文件的任何引用。對于配置了相應(yīng)密碼的設(shè)備,按睡眠/喚醒按鈕會鎖定屏幕,并強制系統(tǒng)丟棄具有完全保護功能的文件的解密密鑰。當(dāng)屏幕被鎖定時,任何訪問相應(yīng)文件的嘗試將失敗。所以如果你有這樣的文件,你應(yīng)該在你的applicationWillResignActive:方法中關(guān)閉對它們的任何引用,并在你的applicationDidBecomeActive:方法中打開新的引用。
重要提示:始終將應(yīng)用程序中的用戶數(shù)據(jù)保存在適當(dāng)?shù)臋z查點。雖然您可以使用應(yīng)用程序狀態(tài)轉(zhuǎn)換來強制對象將未保存的更改寫入磁盤,但不要等待應(yīng)用程序狀態(tài)轉(zhuǎn)換來保存數(shù)據(jù)。例如,管理用戶數(shù)據(jù)的視圖控制器應(yīng)在其被忽略時保存其數(shù)據(jù)。
響應(yīng)臨時中斷
當(dāng)出現(xiàn)基于警報的中斷(例如來電)時,應(yīng)用程序暫時移動到非活動狀態(tài),以便系統(tǒng)可以提示用戶如何繼續(xù)。該應(yīng)用保持在此狀態(tài),直到用戶關(guān)閉警報。此時,應(yīng)用程序返回到活動狀態(tài)或移動到背景狀態(tài)。圖4-3顯示了當(dāng)發(fā)生基于警報的中斷時,通過應(yīng)用程序的事件流程。

圖4-3處理基于警報的中斷
顯示橫幅的通知不會以基于警報的通知的方式停用您的應(yīng)用程序。相反,橫幅放置在應(yīng)用程序窗口的頂部邊緣,您的應(yīng)用程序?qū)⒗^續(xù)像以前一樣接收觸摸事件。但是,如果用戶拉下橫幅以顯示通知中心,則您的應(yīng)用程序?qū)⒁苿拥椒腔顒訝顟B(tài),就像發(fā)生基于警報的中斷一樣。您的應(yīng)用程式仍處于停用狀態(tài),直到使用者解除通知中心或啟動其他應(yīng)用程式。此時,您的應(yīng)用程序?qū)⒁苿拥较鄳?yīng)的活動或背景狀態(tài)。用戶可以使用“設(shè)置”應(yīng)用來配置哪些通知顯示橫幅并顯示警報。
按睡眠/喚醒按鈕是另一種類型的中斷,導(dǎo)致臨時停用應(yīng)用程序。當(dāng)用戶按此按鈕時,系統(tǒng)會禁用觸摸事件,將應(yīng)用程序移動到后臺,將應(yīng)用程序的applicationState屬性的值設(shè)置為UIApplicationStateBackground,并鎖定屏幕。鎖定屏幕會對使用數(shù)據(jù)保護加密文件的應(yīng)用程序帶來額外的后果。這些后果在您的應(yīng)用程序暫時中斷時應(yīng)該怎么做。
當(dāng)您的應(yīng)用程序進入前臺時該怎么辦
回到前臺是您的應(yīng)用程序重新啟動它移動到后臺停止的任務(wù)的機會。移動到前景時出現(xiàn)的步驟如圖4-4所示。applicationWillEnterForeground:方法應(yīng)該撤消在applicationDidEnterBackground:method中完成的任何內(nèi)容,而applicationDidBecomeActive:方法應(yīng)該繼續(xù)執(zhí)行與啟動時相同的激活任務(wù)。

圖4-4從背景轉(zhuǎn)移到前景
注意:當(dāng)您的應(yīng)用程序重新進入前景時,UIApplicationWillEnterForegroundNotification通知也可用于跟蹤。您的應(yīng)用程序中的對象可以使用默認通知中心注冊此通知。
準備處理排隊通知
處于掛起狀態(tài)的應(yīng)用程序必須準備好處理任何排隊的通知,當(dāng)它返回到前臺或后臺執(zhí)行狀態(tài)。暫停的應(yīng)用程序不執(zhí)行任何代碼,因此無法處理與方向更改,時間更改,偏好更改以及影響應(yīng)用的外觀或狀態(tài)的其他許多相關(guān)的通知。為了確保這些更改不會丟失,系統(tǒng)會排隊許多相關(guān)的通知,并在應(yīng)用程序再次開始執(zhí)行代碼(前臺或后臺)時將其發(fā)送到應(yīng)用程序。為了防止您的應(yīng)用程序在恢復(fù)通知時變得超負荷,系統(tǒng)會將事件合并,并提供一個單一的相關(guān)類型的通知(反映自應(yīng)用程序被暫停后的凈更改)。
表4-1列出了可以合并并交付給您的應(yīng)用程序的通知。這些通知中的大多數(shù)都直接發(fā)送給已注冊的觀察員。一些與設(shè)備方向更改相關(guān)的內(nèi)容通常被系統(tǒng)框架截取,并以另一種方式傳送到您的應(yīng)用程序。
表4-1提供給醒來的應(yīng)用程序的通知
事件
通知
連接或斷開附件。
EAAccessoryDidConnectNotification
EAAccessoryDidDisconnectNotification
設(shè)備方向改變。
UIDeviceOrientationDidChangeNotification
除了此通知之外,視圖控制器會自動更新其界面方向。
有一個顯著的時間變化。
UIApplicationSignificantTimeChangeNotification
電池電量或電池狀態(tài)發(fā)生變化。
UIDeviceBatteryLevelDidChangeNotification
UIDeviceBatteryStateDidChangeNotification
接近狀態(tài)發(fā)生變化。
UIDeviceProximityStateDidChangeNotification
受保護文件的狀態(tài)發(fā)生變化。
UIApplicationProtectedDataWillBecomeUnavailable
UIApplicationProtectedDataDidBecomeAvailable
外部顯示器被連接或斷開。
UIScreenDidConnectNotification
UIScreenDidDisconnectNotification
顯示屏的畫面模式發(fā)生變化。
UIScreenModeDidChangeNotification
您的應(yīng)用程序通過“設(shè)置”應(yīng)用程序暴露的首選項已更改。
NSUserDefaultsDidChangeNotification
當(dāng)前語言或區(qū)域設(shè)置已更改。
NSCurrentLocaleDidChangeNotification
用戶的iCloud帳戶的狀態(tài)已更改。
NSUbiquityIdentityDidChangeNotification
排隊的通知在應(yīng)用程序的主運行循環(huán)中傳遞,通常在任何觸摸事件或其他用戶輸入之前提供。大多數(shù)應(yīng)用程序應(yīng)該能夠快速處理這些事件,以至于在恢復(fù)時不會造成任何明顯的滯后。但是,如果您的應(yīng)用程序從后臺狀態(tài)返回時顯示為緩慢,請使用“儀器”來確定您的通知處理程序代碼是否導(dǎo)致延遲。
返回前臺的應(yīng)用程序也會收到自上次更新以來被標記為臟的任何視圖的視圖更新通知。在后臺運行的應(yīng)用程序仍然可以調(diào)用setNeedsDisplay或setNeedsDisplayInRect:方法來請求更新其視圖。但是,由于視圖不可見,系統(tǒng)會將請求合并,并在應(yīng)用程序返回前臺后更新視圖。
處理iCloud更改
如果iCloud的狀態(tài)出于任何原因而更改,系統(tǒng)會向您的應(yīng)用提供NSUbiquityIdentityDidChangeNotification通知。用戶登錄或退出iCloud帳戶時,iCloud的狀態(tài)會發(fā)生變化,或啟用或禁用文檔和數(shù)據(jù)的同步。此通知是您的應(yīng)用程序提示更新緩存和任何與iCloud相關(guān)的用戶界面元素以適應(yīng)更改。例如,當(dāng)用戶注銷iCloud時,應(yīng)刪除對所有基于iCloud的文件或數(shù)據(jù)的引用。
如果您的應(yīng)用程序已經(jīng)提示用戶是否在iCloud中存儲文件,請在iCloud狀態(tài)更改時再次提示。在第一次提示用戶后,將用戶的選擇存儲在應(yīng)用程序的本地首選項中。然后,您可能需要使用設(shè)置包或應(yīng)用程序中的選項來顯示該偏好。但不要再次重復(fù)提示,除非該偏好目前不在用戶默認數(shù)據(jù)庫中。
處理區(qū)域設(shè)置更改
如果用戶在應(yīng)用程序暫停時更改當(dāng)前區(qū)域設(shè)置,則可以使用NSCurrentLocaleDidChangeNotification通知來強制更新任何包含區(qū)域設(shè)置敏感信息的視圖,例如,當(dāng)應(yīng)用程序返回到前臺時,日期,時間和數(shù)字。當(dāng)然,避免與語言環(huán)境有關(guān)的問題的最好辦法就是編寫代碼,方便您更新視圖。例如:
檢索NSLocale對象時,請使用autoupdatingCurrentLocale類方法。此方法返回一個自動更新自身以響應(yīng)更改的區(qū)域設(shè)置對象,因此您不需要重新創(chuàng)建它。但是,當(dāng)區(qū)域設(shè)置更改時,您仍然需要刷新包含從當(dāng)前區(qū)域設(shè)置派生的內(nèi)容的視圖。
每當(dāng)當(dāng)前的區(qū)域設(shè)置信息發(fā)生變化時,重新創(chuàng)建任何緩存的日期和數(shù)字格式化對象。
有關(guān)將代碼國際化以處理區(qū)域設(shè)置更改的更多信息,請參閱國際化和本地化指南。Internationalization and Localization Guide.
處理您應(yīng)用程序設(shè)置的更改
如果您的應(yīng)用具有由設(shè)置應(yīng)用程序管理的設(shè)置,則應(yīng)遵循NSUserDefaultsDidChangeNotification通知。由于用戶可以在您的應(yīng)用程序被暫停或在后臺修改設(shè)置,因此您可以使用此通知來響應(yīng)這些設(shè)置中的任何重要更改。在某些情況下,響應(yīng)此通知可以幫助關(guān)閉潛在的安全漏洞。例如,電子郵件程序應(yīng)該響應(yīng)用戶帳戶信息的更改。不監(jiān)視這些更改可能會導(dǎo)致隱私或安全問題。具體來說,即使帳戶不再屬于該用戶,當(dāng)前用戶也可以使用舊的帳戶信息發(fā)送電子郵件。
在收到NSUserDefaultsDidChangeNotification通知后,您的應(yīng)用程序應(yīng)重新加載任何相關(guān)設(shè)置,如有必要,請重新設(shè)置用戶界面。如果密碼或其他安全相關(guān)信息發(fā)生變化,您還應(yīng)隱藏任何先前顯示的信息,并強制用戶輸入新密碼。
當(dāng)您的應(yīng)用程序進入后臺時該怎么辦
從前臺執(zhí)行到后臺執(zhí)行時,請使用應(yīng)用程序委托的applicationDidEnterBackground:方法執(zhí)行以下操作:
準備好應(yīng)用程序的圖片。當(dāng)您的applicationDidEnterBackground:方法返回時,系統(tǒng)會拍攝您應(yīng)用的用戶界面,并使用生成的圖像進行轉(zhuǎn)換動畫。如果界面中的任何視圖包含敏感信息,則應(yīng)在applicationDidEnterBackground:method返回之前隱藏或修改這些視圖。如果您在視圖層次結(jié)構(gòu)中添加新視圖作為此過程的一部分,則必須強制這些視圖繪制自己,如“準備應(yīng)用程序快照”中所述。Prepare for the App Snapshot.
保存任何相關(guān)的應(yīng)用狀態(tài)信息。在進入后臺之前,您的應(yīng)用程序應(yīng)該已經(jīng)保存了所有關(guān)鍵的用戶數(shù)據(jù)。使用轉(zhuǎn)換到背景來保存應(yīng)用程序狀態(tài)的最后一分鐘更改。
根據(jù)需要釋放內(nèi)存釋放您不需要的任何緩存數(shù)據(jù),并執(zhí)行可能會減少應(yīng)用程序內(nèi)存占用的簡單清理。具有大內(nèi)存占用的應(yīng)用程序是系統(tǒng)首先要終止的,因此可以釋放圖像資源,數(shù)據(jù)高速緩存以及您不再需要的任何其他對象。有關(guān)更多信息,請參閱減少內(nèi)存占用。Reduce Your Memory Footprint.
您的應(yīng)用程序委托的applicationDidEnterBackground:方法大約需要5秒鐘完成任務(wù)并返回。實際上,這種方法應(yīng)盡可能快地返回。如果方法在時間用完之前沒有返回,您的應(yīng)用程序?qū)⒈粡膬?nèi)存中刪除。如果還需要更多時間來執(zhí)行任務(wù),請調(diào)用beginBackgroundTaskWithExpirationHandler:方法來請求后臺執(zhí)行時間,然后在輔助線程中啟動任何長時間運行的任務(wù)。無論是否啟動任何后臺任務(wù),applicationDidEnterBackground:方法必須在5秒內(nèi)退出。
注意:除了調(diào)用applicationDidEnterBackground:方法外,系統(tǒng)還會發(fā)送UIApplicationDidEnterBackgroundNotification通知。您可以使用該通知將清理任務(wù)分發(fā)到應(yīng)用程序的其他對象。
根據(jù)應(yīng)用程序的功能,應(yīng)用程序在移動到背景時應(yīng)該執(zhí)行其他操作。例如,任何活動的Bonjour服務(wù)應(yīng)該被暫停,應(yīng)用程序應(yīng)該停止調(diào)用OpenGLES函數(shù)。有關(guān)您的應(yīng)用程序在移動到背景時應(yīng)該執(zhí)行的操作的列表,請參閱作為負責(zé)任的后臺應(yīng)用程序。Being a Responsible Background App
后臺過渡周期
當(dāng)用戶按下“主頁”按鈕時,按睡眠/喚醒按鈕,或者系統(tǒng)啟動另一個應(yīng)用程序,前臺應(yīng)用程序轉(zhuǎn)換到非活動狀態(tài),然后轉(zhuǎn)換到背景狀態(tài)。這些轉(zhuǎn)換導(dǎo)致調(diào)用app代理的applicationWillResignActive:和applicationDidEnterBackground:方法,如圖4-5所示。從applicationDidEnterBackground:方法返回后,大多數(shù)應(yīng)用程序不久之后就會移動到暫停狀態(tài)。請求特定后臺任務(wù)(如播放音樂)或從系統(tǒng)請求一點額外執(zhí)行時間的應(yīng)用程序可能會持續(xù)運行一段時間。

圖4-5從前臺移動到背景
準備應(yīng)用程序快照
應(yīng)用程序委托的applicationDidEnterBackground:方法返回后不久,系統(tǒng)會收到應(yīng)用程序的Windows快照。同樣,當(dāng)應(yīng)用程序被喚醒以執(zhí)行后臺任務(wù)時,系統(tǒng)可以采取新的快照來反映任何相關(guān)的更改。例如,當(dāng)應(yīng)用程序被喚醒以處理下載的項目時,系統(tǒng)將采取新的快照,以便可以反映由項目合并引起的任何更改。系統(tǒng)在多任務(wù)UI中使用這些快照圖像來顯示應(yīng)用程序的狀態(tài)。
如果在進入后臺更改視圖時,可以調(diào)用主視圖的snapshotViewAfterScreenUpdates:方法來強制執(zhí)行這些更改。在視圖上調(diào)用setNeedsDisplay方法對快照無效,因為在下一個繪圖周期之前拍攝快照,因此防止任何更改被渲染。調(diào)用值為“YES”的snapshotViewAfterScreenUpdates:method將立即更新快照機器使用的底層緩沖區(qū)。
減少你的記憶足跡
每個應(yīng)用程序應(yīng)該在進入后臺釋放盡可能多的內(nèi)存。系統(tǒng)嘗試盡可能多地保留內(nèi)存中的應(yīng)用程序,但是當(dāng)內(nèi)存不足時,它會終止掛起的應(yīng)用程序以回收該內(nèi)存。在后臺消耗大量內(nèi)存的應(yīng)用程序是第一個要終止的應(yīng)用程序。
實際上,您的應(yīng)用程序應(yīng)該在不再需要的時候刪除對對象的強引用。刪除強引用使編譯器能夠立即釋放對象,以便可以回收對應(yīng)的內(nèi)存。但是,如果要緩存某些對象以提高性能,則可以等到應(yīng)用程序轉(zhuǎn)換到后臺才能刪除對它們的引用。
您應(yīng)該盡快刪除強引用的對象的一些示例包括:
您創(chuàng)建的圖像對象。 (有些UIImage的方法可以返回由系統(tǒng)自動清除底層圖像數(shù)據(jù)的圖像。有關(guān)更多信息,請參閱UIImage類參考概述中的討論。)
可以從磁盤重新加載的大型媒體或數(shù)據(jù)文件
您的應(yīng)用程序不需要的任何其他對象,稍后可以重新創(chuàng)建
為了幫助您減少應(yīng)用程序的內(nèi)存占用空間,當(dāng)應(yīng)用程序移動到后臺時,系統(tǒng)會自動清除代表應(yīng)用程序分配的一些數(shù)據(jù)。
系統(tǒng)清除所有Core Animation層的后備存儲。此功能不會從應(yīng)用程序的圖層對象中刪除內(nèi)存,也不會更改當(dāng)前圖層屬性。它只是防止這些圖層的內(nèi)容出現(xiàn)在屏幕上,這表明該應(yīng)用程序在后臺應(yīng)該不會發(fā)生。
它會刪除對緩存圖像的任何系統(tǒng)引用。
它刪除了對其他系統(tǒng)管理的數(shù)據(jù)高速緩存的強引用。