iOS應用程式狀態切換相關

來源:互聯網
上載者:User

http://blog.csdn.net/duanyipeng/article/details/7101829

一、iOS應用程式狀態機一共有五種狀態:

1. Not running:應用還沒有啟動,或者應用正在運行但是途中被系統停止。

2. Inactive:當前應用正在前台運行,但是並不接收事件(當前或許正在執行其它代碼)。一般每當應用要從一個狀態切換到另一個不同的狀態時,中途過渡會短暫停留在此狀態。唯一在此狀態停留時間比較長的情況是:當使用者鎖屏時,或者系統提示使用者去響應某些(諸如電話來電、有未讀簡訊等)事件的時候。

3. Active:當前應用正在前台運行,並且接收事件。這是應用正在前台運行時所處的正常狀態。

4. Background:應用處在後台,並且還在執行代碼。大多數將要進入Suspended狀態的應用,會先短暫進入此狀態。然而,對於請求需要額外的執行時間的應用,會在此狀態保持更長一段時間。另外,如果一個應用要求啟動時直接進入後台運行,這樣的應用會直接從Not running狀態進入Background狀態,中途不會經過Inactive狀態。比如沒有介面的應用。注此處並不特指沒有介面的應用,其實也可以是有介面的應用,只是如果要直接進入background狀態的話,該應用介面不會被顯示。

5. Suspended:應用處在後台,並且已停止執行代碼。系統自動的將應用移入此狀態,且在此舉之前不會對應用做任何通知。當處在此狀態時,應用依然駐留記憶體但不執行任何程式碼。當系統發生低記憶體警示時,系統將會將處於Suspended狀態的應用清除出記憶體以為正在前台啟動並執行應用提供足夠的記憶體。

如:

注意:運行在iOS3.2或更早期版本作業系統之上的應用並不進入後background和suspended狀態。另外,一些即使運行在iOS4或更新版本作業系統但是不支援多任務或後台執行的應用,也不會進入background和suspended狀態。相應的這些應用在從前台運行狀態離開時會直接被終止。

大多時候狀態轉換通過調用你的應用委派物件繼承的Delegate方法來完成。開發人員可以在提供的這些繼承方法中做任何事,以響應狀態轉換。相關繼承的方法及介紹如下所示:

application:didFinishLaunchingWithOptions:   這是程式啟動時調用的函數。可以在此方法中加入初始化相關的代碼。

applicationDidBecomeActive:  應用在準備進入前台運行時執行的函數。(當應用從啟動到前台,或從後台轉入前台都會調用此方法)

applicationWillResignActive:   應用當前正要從前台運行狀態離開時執行的函數。

applicationDidEnterBackground: 此時應用處在background狀態,並且沒有執行任何代碼,未來將被掛起進入suspended狀態。

applicationWillEnterForeground:  當前應用正從後台移入前台運行狀態,但是當前還沒有到Active狀態時執行的函數。

applicationWillTerminate:  當前應用即將被終止,在終止前調用的函數。如果應用當前處在suspended,此方法不會被調用。

 

二、關於main函數,UIApplication類和UIApplication代理類

每一個iPhone程式都包含一個UIApplication對象,它管理整個程式的生命週期,從載入第一個顯示介面開始,並且監聽系統事件、程式事件調度整個程式的執行。

int main(int argc, char *argv[]) {  
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
    int retVal = UIApplicationMain(argc, argv, nil, nil);  
    [pool release];  
    return retVal;  

在main函數中第二行代碼UI Application Main(argc, argv, nil, nil);對UIApplication對象進行了初始化,這個對象是隱含的,這個方法除了argc 和 argv 參數外,另外這個函數還有兩個字串參數來識別UI Application類和UI Application代理類,在這裡預設是2個nil,第一個參數為nil就預設把UI Application類作為預設值進行初始化,可以在這裡不填nil而是使用自己定義的UI Application子類。至於第二個參數nil,這裡有了UI Application對象怎麼又出來一個UI Application代理類對象呢?這裡需要說明UI Application對象說是管理整個程式的生命週期其實它是什麼具體的事情都不幹,它只負責監聽事件當需要做實際工作的時候就交給UI Application代理類去做,UI Application相當於傳令官負責只把命令傳達給UI Application代理類這個士兵,然後由這個士兵真正去衝鋒陷陣,所以需要給UI Application對象設定代理類。

 

三、 iOS應用狀態切換:

1. 應用啟動周期

     當應用啟動時,將從Not running狀態進入foreground或者直接進入background運行。進入前台時,其實最終是要進到Active狀態,中途會先短暫進入到Inactive狀態。在應用啟動時,系統會建立一個process和一個主thread,並且在主thread中調用main函數,即上面二提到的。 main函數在建立工程時由Xcode自動產生。main函數負責UIApplication對象初始化,及設定UIApplication代理類等等。在應用初始化並準備進到前台運行之前的大部分工作都在main函數中完成。

應用被啟動直到前台啟動並執行過程如,右側部分為調用的UIApplication代理類的方法。

如果你的應用要求啟動後直接進入到Backgroundu狀態,則對應的啟動過程和上稍有區別,主要不同是,上面的應用是進入到active,而你的應用要進入到background,並且處理事件,當沒有事件處理時,會被掛起進入到Suspended狀態。如所示。

 

需要注意的一點是:對於從Not running狀態直接進入到background狀態的應用,在啟動進入到background狀態時,如果應用有介面,系統仍然會載入使用者介面檔案,只是不會顯示在應用的window上面。
    為了在程式中確定你的程式是進入到了foreground還是background,你可以在application:didFinishLaunchingWithOptions:   方法中檢測UIApplication類對象的applicationState屬性,如果應用進入到了foreground,則屬性值為UIApplicationStateInactive,如果進入到了background,則為UIApplicationStateBackground。

檢測範例程式碼:

UIApplicationState state = [UIApplication sharedApplication].applicationState;
    return (state==UIApplicationStateActive || state==UIApplicationStateInactive );

    註:當應用啟動時要求開啟一個URL,則此類應用的啟動過程和三中的兩個圖又有稍微區別, 具體如下:

具有自訂URL模式的應用必須能夠處理所有傳遞給它的URLs。所有的URL都是傳遞給應用的代理來處理,無論當前應用是處在啟動階段或是正在運行running或是在後台background。為了能夠處理URL請求,你的應用代理必須實現下面的介面方法:

(1)使用application:didFinishingLaunchingWithOptions:方法檢索URL資訊,並且決定是否想要開啟這個URL,這個方法只有在應用被啟動的時候調用。

(2)iOS4.2或更新的版本,使用方法application:openURL:sourceApplication:annotation:方法去開啟檔案。

(3)iOS4.1或更老的版本,使用方法application:handleOpenURL:方法去開啟檔案。

當URL請求到達時,如果你的應用沒在正在運行,則會被啟動並且移到前台運行以開啟URL。你的application:didFinishingLaunchingWithOptions:方法實現中應該包含從選項字典options dictionary中檢索URL並且判斷該應用能否開啟它的部分。如果能夠開啟,則返回YES,讓方法application:openURL:sourceApplication:annotation:或方法application:handleOpenURL:去處理具體的URL開啟過程。對於要求啟動時開啟URL的應用,啟動順序如所示:

當URL請求到來時,如果你的應用正在background運行或被suspended,它將會被移到前台以開啟URL。之後不久,系統將會調用應用代理的application:openURL:sourceApplication:annotation:方法去檢測URL並開啟它。如果你的應用代理沒有實現這個方法(或者當前系統是iOS4.1或更老的版本),系統將會調用應用代理的application:handleOpenURL:方法來代替。下面是喚醒後台或掛起的應用,去開啟URL的程式執行流程,如所示:

支援自訂URL模式的應用,可以在應用啟動和去處理URL之前,這個過程之間指定不同的啟動畫面映像。具體細節,請看Apple官方文檔iPhoneAppProgrammingGuide.pdf第85頁,“Providing Launch Images for Custom URL Schemes”。

 

2. 響應中斷

當一個基於警告的中斷(諸如電話來電)發生時,應用會暫時從active狀態切換到Inactive狀態,以給系統提供機會提示使用者,讓使用者決定如何處理。在使用者決定如何處理此中斷警告之前,應用將一直處於Inactive狀態。 在使用者做出選擇後,當前應用或者回到active狀態繼續運行,或者直接切換到background狀態以讓位於其它的應用運行。此種情況下,應用執行流程如所示:

在iOS5中,notification,特指顯示banner方式的notification,並不會像上面的中斷一樣使當前處於active狀態的應用程式切換到Inactive狀態。此類通知的banner放置在你的應用視窗的上邊沿之上,所以你的應用依然處在active狀態,並且繼續像以前一樣接收touch events。但是,如果使用者拉下banner去呈現通知中樞內容時,當前應用將會和上面基於警告的中斷一樣切換到inactive狀態。此時應用將一直處於Inactive狀態直到使用者對拉下的banner通知做出處理,或許僅僅清除通知或者啟動另外一個應用。相應的當前應用要麼切換回active狀態繼續運行或者切換到background狀態。使用者可以通過Settings應用來配置哪些Notifications以banner的形式顯示,哪些以alert警告的形式顯示。

         使用者按“休眠/喚醒”鍵是另外一種類型的中斷,這類中斷促使應用被deactived,當使用者按下“休眠/喚醒”鍵時,系統除能觸摸事件,deactivate當前的應用,並且鎖屏。針對使用資料保護進行加密檔案的應用,鎖屏事件除了上面的deactivated應用,除能觸控事件之外還有其它的處理過程。

當中斷髮生時,會做什嗎?

對於基於警告的中斷將會導致使用者暫時對應用失去控制。當前應用繼續在前台foreground運行,但是不再接收任何觸控事件。(事實上,應用只是不再接收觸控類事件,其它類型的事件比如accelerometer事件,和通知Notification,應用仍然接收。)所以為了響應這些變化,應用需要在applicationWillResignActive:方法中做以下工作:

(1)停止timers及終止其它週期性任務。

(2)停止任何正在啟動並執行中繼資料查詢。

(3)不再初始化任何新任務。

(4)暫停電影播放(在AirPlay上的播放除外)

(5)遊戲進入暫停狀態。

(6)恢複OpenGL ES幀率。

(7)暫停任何正在臨界區執行的分發隊列或操作隊列。(當然,當應用處於inactive狀態時,應用仍然可以繼續處理網路請求以及其它一些對時間敏感的背景工作)

        當應用恢複切換回active狀態時,將會在applicationDidBecomeActive:方法中恢複應用被掛起時執行applicationWillResignActive:方法中所做的所有工作。因此,當應用重新被啟用reactivate時,應用應該重啟timers,恢複任何分發隊列,以及恢複OpenGL ES幀率。但是,遊戲不應該自動回復運行,應該繼續保持在暫停狀態直到使用者手動恢複它們。

        當使用者按下“休眠/喚醒” 鍵時,帶有NSFileProtectionComplete保護選項需要對檔案進行保護的應用必須關閉所有對檔案的引用。對於帶有密碼的裝置,按下“休眠/喚醒”鍵時,鎖屏,並且強制系統扔掉解密密鑰,以使完全保護使能。當屏被鎖時,任何嘗試訪問相應受保護檔案的操作都將fail。所以如果你的應用中有此類受保護的檔案時,你應該在applicationWillResignActive:方法中關閉所有對這些檔案的引用,並且在applicationDidBecomeActive:方法中重新開啟對此類檔案的引用。

在通話過程中,調整你的應用的UI:

當使用者正在接電話,並且返回你的應用繼續保留,此時狀態列的高度應該增加以反應使用者正在通話的事實。相似的,當使用者結束通話時,狀態列的高度應該縮減恢複常規高度。處理狀態列高度變化的最好方法是使用view controllers去管理你的應用views。當狀態列frame size改變時,view controllers會自動調整它們所管理的所有內部視圖。

如果你的應用因為某些原因而沒有使用view controllers,則你應該手動響應狀態列frame size的變化,具體即通過註冊UIApplicationDidChangeStatusBarFrameNotification通知來實現。通知處理函數handler應該擷取狀態列的高度並且使用這些資料來適度調整當前應用所包含視圖的高度。

 

3. 切向後台background狀態

當使用者按下"Home"鍵或者系統啟動另外一個應用時,前台foreground應用首先切換到Inactive狀態,然後切換到Background狀態。此轉換將會導致先後調用應用代理的applicationWillResignActive:和applicationDidEnterBackground:方法。在applicationDidEnterBackground:方法返回後,大部分應用在之後不久轉入suspended狀態。對於請求特定後台background任務的應用,比如播放音樂應用,或者那些請求需要額外執行時間的應用,可能會繼續執行更長一段時間。具體流程如所示:

註:應用從froeground切換到background只有在支援多任務並且運行iOS4.0或更新版本系統的裝置上才會發生。所有其它的情況,應用不是切向後台,而是直接終止,並且從記憶體中清除。

應用切向後台background時應該做什麼:

應用可以在applicationDidEnterBackground:方法中做些切向background狀態前需要做的一些準備工作,當切向background狀態時,所有的應用需要做以下事情:

(1)應用介面快照。當applicationDidEnterBackground:方法返回時,系統儲存應用介面的快照,並且使用快照圖片作為轉換動畫。如果在你的應用介面中有涉及到敏感資訊的視圖,則你應該在applicationDidEnterBackground:方法返回前隱藏或者修改這些視圖。

(2)儲存使用者資料和應用狀態資訊。所有沒有儲存的改變都應該在切向background狀態前寫入磁碟以儲存。這一步是必須的,因為你的應用在後台時很有可能因為多種其它原因而被很快kill掉。根據需要你可以在background thread後台線程中執行這些操作。

(3)釋放儘可能多的記憶體資源。

applicationDidEnterBackground:方法允許最多有5秒的時間去完成任何任務然後返回。實際中,此方法應該儘可能快的返回。如果在時間到期之後,此方法沒有返回,則應用即被kill掉,並且清除所佔用的記憶體。如果你的應用確實需要更多的時間去執行任務,可以調用beginBackgroundTaskWithExpirationHandler:方法請求後台執行時間,然後啟動一個能長期執行任務的線程。無論你是否啟動一個執行背景工作的線程,applicationDidEnterBackground:方法都必須在5秒後退出。

註:UIApplicationDidEnterBackgroundNotification通知也會發送,以讓應用對此通知感興趣的部分知道當前應用正切向background狀態。你的應用中的對象可以使用預設的通知中樞註冊這個通知。

依據不同的應用場合,應用切向後台時還有很多其它的事情需要做,比如active狀態的Bonjour服務應該暫停,應用應該停止調用OpenGL ES函數。

因為前台應用在使用系統資源和硬體時一直比後台應用具有更高的優先權。運行在背景應用應該對此差異有心理準備,並且在後台運行時要調整它們的訪問資源行為。特別的,當應用切向background時尤其要遵循以下幾點:

(1)不要在應用代碼中調用任何OpenGL ES的東西。當應用在後台運行時不可以建立EAGLContext對象或者發出任何OpenGL ES繪畫命令,使用這些調用將會導致應用立即被kill掉。應用也必須保證先前提交發出的所有命令在應用切向background狀態前都已執行完畢。具體細節請參考“OpenGL ES Programming Guide for iOS”中“Implementing a Multitasking-aware OpenGL ES Application”部分。

(2)在應用掛起suspended之前取消所有Bonjour相關的服務。當應用轉向後台,並且在被掛起前,應用應該unregister Bonjour服務並且關掉任何和網路服務相關的sockets監聽。掛起的應用是沒法響應這些服務要求的。如果你的應用不關掉這些和Bonjour相關的服務,當應用被掛起的時候,系統會自動幫你關掉這些服務。

(3)在基於網路sockets的應用中,需要處理串連失敗的情況。當你的應用因為某些原因而被掛起時,系統可能會拆除socket串連。只要你的應用對儘可能多的網路錯誤情況都有很好的處理,像丟掉訊號等,此類問題不會導致你的應用出現不正常。當應用從後台退出恢複執行時,如果遇到sockets使用錯誤,簡單的重建socket串連即可。

(4)在切向background狀態前儲存應用狀態。在低記憶體警示時,後台應用可能會被清除出記憶體以釋放空間。處於suspended狀態的應用被優先清除記憶體,並且在被清除前不會給出任何通知。因此,當應用切入background狀態前一定要儲存足夠多的應用狀態資訊以便後面恢複時使用。

(5)當切向後台時,釋放所有不再需要的記憶體。如果你的應用保持著一個很大的記憶體緩衝對象(比像),則切入後台前,釋放所有的對這些緩衝對象的引用。

(6)在被掛起前停止使用系統共用資源。使用系統共用資源(比如Address Book或Calendar Data)的應用,在被掛起前必須停止對這些共用資源的使用。對這些資源的使用,前台應用具有更高的優先使用權,如果發現你的應用在被掛起後還沒有停止對這些共用資源的使用,則應該將被kill掉。

(7)避免更新應用視窗和視圖。當應用處在後台時,應用視窗和視圖是不可見的,所以不需要更新它他。儘管在後台建立和操縱視窗和視圖對象並不會導致應用被kill掉,但是可以考慮將這些工作延遲到應用返回前台時執行。

(8)響應外部附件串連和失去串連通知。針對和外部附件有通訊的應用,當應用切向background狀態時,系統會發送一個disconnection通知。應用必須註冊此通知並且使用它去關掉當前的附件訪問session。當應用返回foreground時,會有一個與之匹配的通知被發送,給應用提供重建立立session的機會。

(9)切向後台時,清除行為警告相關的資源。為了在應用相互切換之間儲存應用上下文,當應用切向後台時,系統並不自動dismiss action sheets(UIActionSheet)和alert views(UIAlertView)。由應用設計者去提供具本的清除方案。對於運行在iOS4.0版本之前的應用,在退出時action sheets和alerts仍然被dismiss掉,以讓應用的取消處理函數有機會去運行。

(10)切向後台時,移除所有敏感視圖資訊。因為系統會快照應用介面並且產生應用程式切換動畫,所以帶有敏感資訊的視圖或視窗必須隱藏或移除,具體原因前面已介紹。

(11)應用在後台運行時執行最少量化的工作。系統給後台啟動並執行應用的執行時間和給前台啟動並執行應用相比,通常非常有限。如果應用在背景播放音頻或者監測位置變化,則應用應該僅關注此任務,所有不必要的任務都應該被延遲。在後台執行時間過長的應用會被系統throttled back或者直接被kill掉。

當應用因為系統記憶體警示需要被清除出記憶體時,應用會調用他的代理的applicationWillTerminate:方法去執行應用退出前的最後的任務。

後台應用的記憶體使用量:

當應用切入background時,每個應用應該釋放儘可能多的實際佔用的記憶體。系統盡量嘗試在記憶體中同時保持盡量多的應用,但是當記憶體即將耗盡時,系統會終止那些掛起suspended的應用以回收記憶體。然而那些消耗很大數量的記憶體同時又處於後台background啟動並執行應用會優先被終止。

實事求是的講,就是當你的應用在不再需要的時候要儘快的移除對那些用過對象的引用。移除引用允許自動引用計數系統去釋放對象並且回收記憶體。然而,如果應用為了改進效能而使用了緩衝,則應用應該在切換至後台狀態前等待並且釋放這些緩衝。下面是一些需要回收的對象的例子:

(1)緩衝的映像對象

(2)比較大的多媒體檔案或資料檔案,這些檔案可以從磁碟重新裝載。

(3)任何應用當前不再需要的對象,並且這些對象後面又可以很容易重新建立。

為了協助您的應用程式,減少其記憶體佔用,系統會自動釋放出許多幕後用於支援您的應用程式的對象。例如:

(1)釋放所有的核心動畫層的備份存放區,以避免這些層繼續在螢幕上顯示,同時又不改變當前層的屬性。並且並不釋放層對象自已。

(2)移除所有對緩衝映像的引用。(如果應用沒有對這些映像強引用,則他們隨後即被移除記憶體)

(3)釋放一些系統管理的其它的資料緩衝。

 

4. 返回前台foreground

如果應用曾被移入後台,相應的任務被停止,則此時返回前台時可以重啟任務繼續執行。應用的applicationWillEnterForeground:方法應該恢複所有在applicationDidEnterBackground:方法所做的工作。同時,applicationDidBecomeActive:方法應該繼續執行在應用啟動時所做的同樣的啟用任務的操作。應用從後台切入前台的程式流程如所示:

註:如果應用在預設的通知中樞註冊了UIApplicationWillEnterForegroudNotification通知,則當應用重新進入前台時,該通知也是可用的。

(1)在應用切向前台被喚醒時處理通知隊列

被掛起的應用要時刻準備當恢複foreground或background狀態時去處理所有的通知隊列。因為應用被掛起時不能執行任何代碼,因此沒有辦法處理那些和諸如方向改變、時間改變、偏好改變、以及其它的影響應用的外觀的行為或狀態等等。為了保證這些改變不丟失,系統將這些相關的通知入隊列,並且當應用恢複foreground或background重新執行代碼時,立即將這些通知發往應用。為了防止應用恢複時因為通知過多而過載,系統會合并事件並且僅傳遞一個能夠反應自從應用被掛起有網路改變的單個通知。

具體通知合并規則如下表所示:

大部分通知直接傳遞給註冊它作的observers,然而像方向改變這樣的通知很明顯是被系統架構解析的,這樣的通知以另外的方式傳遞給應用。

通知隊列典型的在任何觸控事件和使用者輸入之前被投遞嚮應用的主運行迴圈main run loop。大多數應用應該能夠足夠快的處理這些事件以致於不會造成應用恢複時有任何明顯的滯後。然而,如果發現你的應用在從後台恢複時看起來明顯獃滯,則可以使用Instruments去確定是否是通知處理代碼正在運行而造成了延遲。一個應用在返回前台時也會接收所有自從上更新後被標記為dirty的視圖的更新通知。處於後台background啟動並執行應用也可以調用setNeedsDisplay或setNeedsDisplayInRect:方法去請求視圖更新。然而,因為這時介面不可見,所以系統合并這些請求並且只有當應用恢複前台後才去更新視圖。

(2)從容的處理本地改變

當應用處於掛起suspended狀態時,如果使用者改變了當前語言設定,則當應用返回前台的時候可以使用NSCurrentLocalDidChaneNotification通知來強制任何包含本地敏感資訊(像日期、時間、數字等等)的視圖進行更新。當然,避免本地資訊相關的事件處理的最好的方法還是以那種更容易更新視圖的方式來寫更新視圖的代碼。比如:

a.使用autoupdatingCurrentLocal類方法來檢索NSLocal對象。此方法返回一個本機物件,該對象響應本地改變並且自動更新自已。所以,你不需要再去重新建立它。然後,當本地資訊改變時,你的應用仍然需要去重新整理那些包含本地資訊的視圖。

b.無論任何時候本地資訊改變時都去重新建立緩衝日期或者數字格式對象。

(3)響應應用設定改變

如果應用程式套件含被Settings應用所管理的設定,則應用應該關注NSUserDefaultsDidChangeNotification通知。因為當你的應用處於後台或被掛起狀態時,使用者可以修改設定,所以你的應用中可以使用這個通知來響應任何重要的設定改變。某些情況下,響應此通知可以協助關掉一些潛在的安全性漏洞。例如,email程式應該響應使用者帳戶資訊的改變,如果不能成功的監測這些改變將會造成一些隱私和安全方面的問題。比如,使用者很有可能發送郵件時還是使用的是老使用者帳戶,即使那個帳戶已經不再屬於該使用者,然而使用者確絲毫不情以為用的就是新帳戶。當應用接收到該通知時,應用應該重新載入所有和設定相關的東西並且適當的複位使用者介面,如果必要的話。比如密碼或其它的安全相關的資訊改變時,應用應該隱藏任何先前顯示的資訊並且強制使用者輸入新密碼。

 

5.應用終止

儘管應用通常被切向後台或被掛起,但是如果有任何下面的情況發生時,應用將被終止並且清除出記憶體:

(1)應用依賴於 iOS4.0以前的版本OS

(2)應用部署在運行iOS4.0版本作業系統的裝置上

(3)當前裝置不支援多任務

(4)應用在Info.plist檔案中包含UIApplicationExitOnSuspend key。

如果應用將被終止時正在前台或後台運行,系統將會調用應用代理的applicationWillTerminate:方法以使應用能做退出前的任何需要的回收處理。你可以使用此方法儲存使用者資料或應用狀態資訊,以供應用隨後重新啟動恢複狀態時使用。該方法最長運行時限為5秒,到期應用即被kill掉並且移除記憶體。

註:應用當前被suspended時,不會調用 applicationWillTerminate:方法。

即使是使用iOS SDK4或更新的版本SDK開發應用,也應該考慮應用在沒有任何通知時被kill掉的情況。使用者可以使用多任務UI很明確的kill掉某個應用。除此之外,如果發生記憶體警示,系統也會從記憶體中移除應用以釋放空間。處於suspended狀態的應用被終止時不會有任何通知。但是如果應用當前正在後台background運行,則當應用要被終止時,系統會調用應用代理的applicationWillTerminate:方法。應用不可以在此方法中申請額外的後台執行時間。

 

6.主運行迴圈main run loop

應用主運行迴圈負責處理所有使用者相關的事件。UIApplication對象在應用啟動時安裝主運行迴圈並且使用此迴圈去處理事件和處理基於視圖的介面更新。正如名字所表明的,該主運行迴圈是在應用的主線程app's main thread中啟動並執行。以此保證所有使用者事件是按照它們被接收時的順序串列的執行。

展示了主運行迴圈的結構以及使用者事件如何導致了應用行為。當使用者和應用互動時,和這些互動相關的事件由系統自動產生並且藉助UIKit設定的特殊連接埠傳遞給應用。事件在應用內部以隊列的形式存在並且一個一個的被分發到應用的主運行迴圈去執行。UIApplication對象是第一個接收事件的對象,並且決定需要如何處理事件。觸控事件通常被分發到應用的主視窗對象,並且最終分發到發生該觸控事件的視圖上面。其它的事件傳遞也許會經過各種各樣的應用對象而與觸控事件傳遞稍微有所不同。

在iOS應用中可以傳遞很多類型的事件。最常見的事件列在下表中:

這些事件類型中的大部分通過應用的主運行迴圈進行傳遞,但是還有一些並不是的。例如:accelerometer事件直接被傳遞到應用指定的accelerometer代理對像。關於系統如何處理大多數類型事件,包括touch、remote control、motion、accelerometer,以及gyroscopic事件,詳見Event Handling Guide for iOS.

一些像觸控、遠端控制類的事件,通常被應用的響應對象處理。響應對象存在於應用的任何地方。(UIApplication對象,view對象,view controller對象等等都是響應對象的例子)。大多數事件是以特定的響應對象為目標,但是也可以被傳遞給其它的響應對象(藉助響應鏈),例如:一個不處理任何事件的view可以將事件傳遞給它的父view或傳遞給view controller。

發生在controls類的視圖(例如button)上的事件的處理過程和發生在其它類型的views上的觸控事件處理過程有些不一樣。因為發生在control類的對象上面的互動行為只有非常有限的幾種,因此這些互動重新打包進active message並且傳遞給合適的目標對象。  這種target-action的設計模式,使應用通過control類型的view對象去觸發一段自訂代碼的執行變得非常容易。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.