2015年2月16日 星期一

iOS App應用程式生命週期(下)

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上,其他事件也是用類似方式。

Processing events in the main run loop







常見事件可以看到下表,大部份的事件用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

開發者指定的物件
使用Core Location framework來接受location events,更多的資訊可參考Location and Maps Programming Guide
Redraw


當View需要更新
重繪事件(Redraw events)不會引發事件相關物件,只是簡單呼叫view去重畫它自己。詳細可以參考Drawing and Printing Guide for iOS

一些事件,像是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
App正在背景執行程式碼,大部份App短暫進入此狀態後就會進入暫停狀態;對於如何在背景狀態執行程式碼,可以參考Background Execution
Suspended
App正在背景但是沒有執行程式碼,系統會自動將Apps進入此狀態,並且不會通知它們。當進入暫時狀態時,App仍然在記憶體中,但是不會執行任何程式碼。當記憶體不足時,系統可能會不通知而直接中斷暫停的App,為了提供更多的記憶體空間給前景App。


大部份App狀態轉換是透過呼叫app delegate object的方法來達成;這些方法是程式撰寫者的機會去處理這些轉換,這些方法簡單說明如下。

App Termination

App必須要準備好隨時被使用者或系統所結束,而且不能等待儲存使用者資料或做其他重要的工作;由系統所引發的結束是App應用程式生命週期正常的一部份。
系統通常會終止App以釋放更多的記憶體空間給其他的應用程式使用,暫停的Apps被中止時不會接受到任何的通知。
假設App正在背景執行,並且尚未暫停,若要中止系統會呼applicationWillTerminate方法。當系統重啟時也不會呼叫此方法。
除了系統中止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採用同步執行。

關於更多GCD同步的技術可以參考Concurrency Programming Guide

沒有留言:

張貼留言