標籤:http color 使用 strong 檔案 os
對於iOS應用程式,關鍵是要知道你的應用程式是否正在前台或後台運行。由於系統資源在iOS裝置上較為有限,一個應用程式必須在後台與前台有不同的行為。作業系統也會限制你的應用程式在背景運行,以提高電池壽命,並提高使用者與前台應用程式的體驗。當應用程式在前台和後台之間切換時,作業系統將會通知您的應用程式。你可以通過這些通知來修改你的應用程式的行為。 當你的應用程式在前台活動時,系統會發送觸摸事件給它進行處理。在UIKit的基礎設施做了大部分的事件傳遞給你的自訂對象工作。所有您需要做的是覆蓋在相應的對象的方法來處理這??些事件。對於控制項,UIKit會通過處理你的觸摸事件,或者其他一些有趣的事情發生時調用您的自訂代碼,比如當文字欄位中的值更改。
1、應用程式的狀態
Not running未運行:程式沒啟動。
Inactive未啟用:程式在前台運行,不過沒有接收到事件。在沒有事件處理情況下程式通常停留在這個狀態。
Active啟用:程式在前台運行而且接收到了事件。這也是前台的一個正常的模式。
Backgroud後台:程式在後台而且能執行代碼,大多數程式進入這個狀態後會在在這個狀態上停留一會。時間到之後會進入掛起狀態(Suspended)。有的程式經過特殊的請求後可以長期處於Backgroud狀態。
Suspended掛起:程式在後台不能執行代碼。系統會自動把程式變成這個狀態而且不會發出通知。當掛起時,程式還是停留在記憶體中的,當系統記憶體低時,系統就把掛起的程式清除掉,為前景程式提供更多的記憶體。
2、各個程式運行狀態時代理的回調 ①告訴代理進程啟動但還沒進入狀態儲存
- - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- NSLog(@"①告訴代理進程啟動但還沒進入狀態儲存");
- return YES;
- }
②告訴代理啟動基本完成程式準備開始運行
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
-
- NSLog(@"②告訴代理啟動基本完成程式準備開始運行");
-
- // Override point for customization after application launch.
-
- self.window.backgroundColor = [UIColor whiteColor];
- [self.window makeKeyAndVisible];
- return YES;
- }
③當應用程式將要入非使用中執行,在此期間,應用程式不接收訊息或事件,比如來電話
- - (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(@"③當應用程式將要入非使用中執行,在此期間,應用程式不接收訊息或事件,比如來電話");
- }
④當應用程式進入活動狀態執行
- - (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(@"④當應用程式進入活動狀態執行");
- }
⑤當程式被推送到背景時候調用。所以要設定後台繼續運行,則在這個函數裡面設定即可
- - (void)applicationDidEnterBackground:(UIApplication *)application
- {
- // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
- // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
- NSLog(@"⑤當程式被推送到背景時候調用");
-
- [application beginBackgroundTaskWithExpirationHandler:^{
-
- NSLog(@"begin Background Task With Expiration Handler");
-
- }];
- }
⑥當程式從後台將要重新回到前台時候調用
- - (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(@"⑥當程式從後台將要重新回到前台時候調用");
- }
⑦當程式將要退出是被調用,通常是用來儲存資料和一些退出前的清理工作。這個需要要設定UIApplicationExitsOnSuspend的索引值
- - (void)applicationWillTerminate:(UIApplication *)application
- {
- // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
- NSLog(@"⑦當程式將要退出是被調用");
- }
⑧當程式載入後執行
- - (void)applicationDidFinishLaunching:(UIApplication *)application
- {
- NSLog(@"⑧當程式載入後執行");
- }
程式啟動時: 2014-07-01 15:55:14.706 LifeCycle[5845:60b] ①告訴代理進程啟動但還沒進入狀態儲存 2014-07-01 15:55:14.708 LifeCycle[5845:60b] ②告訴代理啟動基本完成程式準備開始運行 2014-07-01 15:55:14.709 LifeCycle[5845:60b] ④當應用程式進入活動狀態執行 按下Home鍵返回主介面: 2014-07-01 15:56:11.756 LifeCycle[5845:60b] ③當應用程式將要入非使用中執行 2014-07-01 15:56:11.814 LifeCycle[5845:60b] ⑤當程式被推送到背景時候調用 再次開啟程式: 2014-07-01 15:57:19.200 LifeCycle[5845:60b] ⑥當程式從後台將要重新回到前台時候調用 2014-07-01 15:57:19.201 LifeCycle[5845:60b] ④當應用程式進入活動狀態執行
3、載入應用程式進入前台
4、載入應用程式進入後台
5、基於警告式響應中斷當出現這種中斷時,我們需要在- (void)applicationWillResignActive:(UIApplication *)application方法中進行如下操作: ①停止timer 和其他周期性的任務 ②停止任何正在啟動並執行請求 ③暫停視頻的播放 ④如果是遊戲那就暫停它 ⑤減少OpenGL ES的幀率 ⑥掛起任何分發的隊列和不重要的操作隊列(你可以繼續處理網路請求或其他時間敏感的背景工作) 當程式回到active狀態,我們需要在- (void)applicationDidBecomeActive:(UIApplication *)application方法中重新開始上述任務。不過遊戲要回到暫停狀態,不能自動開始。
6、進入後台運行當應用程式進入後台時,我們應該做些什嗎? 儲存使用者資料或狀態資訊,所有沒寫到磁碟的檔案或資訊,在進入後台時,最後都寫到磁碟去,因為程式可能在後台被殺死。 釋放儘可能釋放的記憶體。 - (void)applicationDidEnterBackground:(UIApplication *)application方法有大概5秒的時間讓你完成這些任務。如果超過時間還有未完成的任務,你的程式就會被終止而且從記憶體中清除。 如果還需要長時間的運行任務,可以在該方法中調用
- [application beginBackgroundTaskWithExpirationHandler:^{
-
- NSLog(@"begin Background Task With Expiration Handler");
-
- }];
應用程式在後台時的記憶體使用量:請求後台已耗用時間和啟動線程來運行長時間啟動並執行任務。 在後台時,每個應用程式都應該釋放最大的記憶體。系統努力的保持更多的應用程式在後台同時 運行。不過當記憶體不足時,會終止一些掛起的程式來回收記憶體,那些記憶體最大的程式首先被終止。 事實上,應用程式應該的對象如果不再使用了,那就應該儘快的去掉強引用,這樣編譯器可以回收這些記憶體。如果你想緩衝一些對象提升程式的效能,你可以在進入後台時,把這些對象去掉強引用。 下面這樣的對象應該儘快的去掉強引用: ①圖片對象 ②你可以重新載入的 大的視頻或資料檔案 ③任何沒用而且可以輕易建立的對象 在後台時,為了減少程式佔用的記憶體,系統會自動在回收一些系統協助你開闢的記憶體。比如: ①系統回收Core Animation的備份存放區。 ②去掉任何系統引用的緩衝圖片 ③去掉系統管理資料緩衝強引用
7、返回前台運行在暫停狀態的應用程式必須準備處理任何排隊的通知時,它返回到前台或後台執行狀態。停用的應用程式不執行任何代碼,因此不能處理與方向的變化,時間的變化,偏好的變化,以及許多其他會影響應用程式的外觀或狀態的通知。為了確保這些更改不會丟失,系統排隊許多相關的通知,並把它們傳遞給應用程式,只要它開始再次執行代碼(無論是在前景或背景)。為了防止由偏快轉為超載與它恢複時通知您的應用程式,該系統凝聚事件,並提供一個單一的通知(每個相互關聯類型),反映了淨變化,因為你的應用程式被暫停。
8、程式終止 程式只要符合以下情況之一,只要進入後台或掛起狀態就會終止: ①iOS4.0以前的系統 ②app是基於iOS4.0之前系統開發的。 ③裝置不支援多任務 ④在Info.plist檔案中,程式包含了 UIApplicationExitsOnSuspend 鍵。 app如果終止了,系統會調用app的代理的方法 - (void)applicationWillTerminate:(UIApplication *)application,這樣可以讓你可以做一些清理工作。你可以儲存一些資料或app的狀態。這個方法也有5秒鐘的限制。逾時後方法會返回程式從記憶體中清除。 注意:使用者可以手工關閉應用程式。
9、The Main Run Loop 主運行迴圈 Main Run Loop負責處理使用者相關的事件。UIApplication對象在程式啟動時啟動main run Loop,它處理事件和更新視圖的介面。看Main Run Loop就知道,它是運行在程式的主線程上的。這樣保證了接收到使用者相關操作的事件是按順序處理的。 使用者操作裝置,相關的操作事件被系統產生並通過UIKit的指定連接埠分發。事件在內部排成隊列,一個個的分發到Main run loop 去做處理。UIApplication對象是第一個接收到時間的對象,它決定事件如何被處理。觸摸事件分發到主視窗,視窗再分發到對應出發觸摸事件的View。其他的事件通過其他途徑分發給其他物件變數做處理。 大部分的事件可以在你的應用裡分發,類似於觸摸事件,遠程操控事件(線控耳機等)都是由app的 responder objects 對象處理的。Responder objects 在你的app裡到處都是,比如:UIApplication 對象,view對象,view controller 對象,都是resopnder objects。大部分事件的目標都指定了resopnder object,不過事件也可以傳遞給其他對象。比如,如果view對象不處理事件,可以傳給父類view或者view controller。