The Main Run Loop
App的main run loop用來處理所有使用者相關的事件,UIApplication物件在開始時會設定main run loop,用來處理事 bv件及畫面的更新;就像名稱所提及,main run loop在App的main thread執行。這樣的機制確保使用者相關的事件,能夠循序的在程式中處理。下圖說明了man run loop的流程。
使用者與iPhone/iPad互動時,系統會根據使用者的互動產生相關事件,並由UIKit傳遞給App。
事件在內部會放到Event queue,並依序傳給main run loop去執行; UIApplication 是第一個接受到這些事件的物件,並且決定誰會處理這些事件。以Touch event為例通常會派送到main window物件,然後會送到發生事件的view上,其他事件也是用類似方式。
常見事件可以看到下表,大部份的事件用main run loop傳遞到app,但是一些則不是;一些事件是透過App開發者提供的委託物件或是程式碼片段。詳細可參考Event Handling Guide for iOS
事件類別
|
傳遞給...
|
註解
|
Touch
|
事件發生時的view object
|
當觸碰螢幕時會發生事件,最初接觸到的Views 是responder objects,當第一個接觸到的未處理,會轉給上層的responder objects來處理。
|
Remote control
Shake motion events
|
Remote control events是由耳機按鈕或其他配件所產生的事件;Shake motion events則是使用者搖晃事件。
| |
Accelerometer
Magnetometer
Gyroscope
|
開發者指定的物件
|
Accelerometer加速感應器可用來精確測量出步行和跑步的距離、Magentometer則是磁力儀,用來偵測附近的磁場、Gyroscope陀螺儀用來指向固定方向,可用來實作指南針。
|
Location
|
開發者指定的物件
| |
Redraw
|
當View需要更新
|
一些事件,像是touch及remote control事件,會由App的responder objects來處理;Responder objects在App中隨處可見,像是UIApplication object、view objects及view controller objects。
大部份事件會傳遞給特定的Responder object,但是也可傳遞給其他的Responder objects(稱之為responder chain)。
控制項(像是Buttons)的Touch事件的處理方式和其他類型的Views不一樣,通常只有固定的幾項互動在這控制項,這些互動會被包裝成Action Messages並傳遞到正確的Target Object。Target-action design pattern讓控制項很容易去觸發在App的自訂程式碼。
Apps 執行狀態
狀態
|
描述
|
Not running
|
App尚未執行。
|
Inactive
|
App正在前景執行但是沒有接受事件(可能正在執行其他程式碼);App通常只會在此狀態一小段時間,就會轉為其他狀態。
|
Active
|
App正在前景執行,也正在接受事件。
|
Background
| |
Suspended
|
App正在背景但是沒有執行程式碼,系統會自動將Apps進入此狀態,並且不會通知它們。當進入暫時狀態時,App仍然在記憶體中,但是不會執行任何程式碼。當記憶體不足時,系統可能會不通知而直接中斷暫停的App,為了提供更多的記憶體空間給前景App。
|
大部份App狀態轉換是透過呼叫app delegate object的方法來達成;這些方法是程式撰寫者的機會去處理這些轉換,這些方法簡單說明如下。
- application:willFinishLaunchingWithOptions:—這方法是您的App在開始時會去呼叫。
- application:didFinishLaunchingWithOptions:—這方法允許您在App要顯示給使用時,可以做最後的初始化。
- applicationDidBecomeActive:— 當App要成為前景時,可在此方法做準備。
- applicationWillResignActive:—當App從Active狀態轉換為InActive時可在此方法做準備。
- applicationDidEnterBackground:—讓你知道你的App正在背景執行,並且隨時會被暫停。
- applicationWillEnterForeground:—讓你知道你的App正在從背景轉換到前景,但是還沒有到Active狀態。
- applicationWillTerminate:— 讓你知道你的App正在被結束,這方法不會被呼叫假設你的App在暫停狀態。
App Termination
App必須要準備好隨時被使用者或系統所結束,而且不能等待儲存使用者資料或做其他重要的工作;由系統所引發的結束是App應用程式生命週期正常的一部份。
系統通常會終止App以釋放更多的記憶體空間給其他的應用程式使用,暫停的Apps被中止時不會接受到任何的通知。
除了系統中止App外,使用者也可以直接使用介面來中止App;由使用者所中止的App就和系統中止暫停的App是一樣的,App並不會接受到任何的通知。
Threads and Concurrency
系統建立App的main thread,而開發者建立額外的thread用來去執行其他工作;就iOS Apps,較傾向的方式是用Grand Central Dispatch (GCD),GCD的觀念是讓你去定義你想做的工作,以及這些工作想執行的優先次序,但是由系統來實際決定最佳的執行方式,而不是自行建立及管理thread。讓系統來管理thread可以簡化開發者要撰寫的程式碼,並且也會有較佳的程式碼正確性及系統效能。當考慮到threads及concurrency,想像以下的情況。
- 操作Views、Core Animation及許多其他UIKit類別時通常會在app的主thread進行操作,但是有些例外,例如以影像為基礎的操作常會在背景thread。
- 長時間的工作應該總是在背景thread執行,例如網路存取、檔案存取、大量資料存取,應用GCD來做同步處理。
- 在App啟動時,盡可能不要在main thread執行任務;在App啟動時應該快將使用者介面設定好。在main thread應該只執行設定使用者介面相關動作,其他任務應在其他的thread採用同步執行。
沒有留言:
張貼留言