1. 程式人生 > 其它 >IOS學習1——IOS應用程式的生命週期及基本架構

IOS學習1——IOS應用程式的生命週期及基本架構

一、應用程式的狀態和多工

有時系統會從app一種狀態切換另一種狀態來響應系統發生的事件。例如,當用戶按下home鍵、電話打入、或其他中斷髮生時,當前執行的應用程式會切換狀態來響應。應用程式的狀態有以下幾種:

  • Not running:app還沒執行
  • Inactive:app執行在foreground但沒有接收事件
  • Active:app執行在foreground和正在接收事件
  • Background:執行在background和正在執行程式碼
  • Suspended:執行在background但沒有執行程式碼

大多數發生狀態轉換時都會呼叫delegate物件對應的方法來響應app的狀態改變。下面彙總了delegate物件的所有方法,當app狀態發生轉換時,你可能會使用到它們。

  • application:willFinishLaunchingWithOptions: - 這個方法是你在啟動時的第一次機會來執行程式碼
  • application:didFinishLaunchingWithOptions: - 這個方法允許你在顯示app給使用者之前執行最後的初始化操作
  • applicationDidBecomeActive: - app已經切換到active狀態後需要執行的操作
  • applicationWillResignActive: - app將要從前臺切換到後臺時需要執行的操作
  • applicationDidEnterBackground: - app已經進入後臺後需要執行的操作
  • applicationWillEnterForeground: - app將要從後臺切換到前臺需要執行的操作,但app還不是active狀態
  • applicationWillTerminate: - app將要結束時需要執行的操作

現在講下app啟動、來回切換app和鎖屏時狀態的切換和呼叫對應哪些delegate物件的方法:

  • app啟動和active/inactive

如圖所示,當app啟動時,首先由not running狀態切換到inactive狀態,此時呼叫application:didFinishLaunchingWithOptions:方法;然後由inactive狀態切換到active狀態,此時呼叫applicationDidBecomeActive:方法。

當app發生中斷時,由active狀態切換到inactive狀態,此時呼叫applicationWillResignActive:方法。

  • 來回切換app

如圖所示,當切換到另一個app時,由狀態active切換到inactive,此時呼叫applicationWillResignActive:方法;然後從inactive狀態切換到running狀態,此時呼叫applicationDidEnterBackground:方法。

而當切換回本來的app時,由running狀態切換到inactive狀態,此時呼叫applicationWillEnterForeground:方法,然後由inactive狀態切換到active狀態,呼叫applicationDidBecomeActive:方法。

  • 鎖屏

如何所示,當手機鎖屏時,由狀態active切換到inactive,此時呼叫applicationWillResignActive:;然後再由inactive狀態切換到running狀態,此時呼叫applicationDidEnterBackground:方法。

更多關於app狀態切換以及呼叫app delegate哪些方法,請觀看WWDC 2011 Session的session_320__adopting_multitasking_in_your_app視訊。

二、應用程式的終止

系統常常是為其他app啟動時由於記憶體不足而回收記憶體最後需要終止應用程式,但有時也會是由於app很長時間才響應而終止。如果app當時執行在後臺並且沒有暫停,系統會在應用程式終止之前呼叫applicationWillTerminate:來儲存使用者的一些重要資料以便下次啟動時恢復到app原來的狀態。

iOS應用程式一般都是由自己編寫的程式碼和系統框架(system frameworks)組成,系統框架提供一些基本infrastructure給所有app來執行,而你提供自己編寫的程式碼來定製app的外觀和行為。因此,瞭解iOS infrastructure和它們如何工作對編寫app是很有幫助的。

三、Main函式入口 所有基於C編寫的app的入口都是main函式,但iOS應用程式有點不同。不同就是你不需要為iOS應用程式而自己編寫main函式,當你使用Xcode建立工程的時候就已經提供了。除非一些特殊情況,否則你不應該修改Xcode提供的main函式實現。示例程式碼如下:

1 #import
2 #import "AppDelegate.h"
3 int main(int argc, char * argv[])
4 {
5     @autoreleasepool {
6         return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
7     } 
8 }

上面例項程式碼中有一個很重要的函式UIApplicationMain,它主要是建立app的幾個核心物件來處理以下過程:

  1. 從可用Storyboard檔案載入使用者介面
  2. 呼叫AppDelegate自定義程式碼來做一些初始化設定
  3. 將app放入Main Run Loop環境中來響應和處理與使用者互動產生的事件

四、應用程式的架構

iOS應用程式都遵循Model-View-Controller的架構,Model負責儲存資料和處理業務邏輯,View負責顯示資料和與使用者互動,Controller是兩者的中介,協調Model和View相互協作。它們的通訊規則如下:

1.  Controller能夠訪問Model和View,Model和View不能互相訪問

2.  當View與使用者互動產生事件時,使用target-action方式來處理

3.  當View需要處理一些特殊UI邏輯或獲取資料來源時,通過delegate或data source方式交給Controller來處理

4.  Model不能直接與Controller通訊,當Model有資料更新時,可以通過Notification或KVO (Key Value Observing)來通知Controller更新View

瞭解iOS的MVC設計模式之後,我們從下圖來了解在MVC模式下iOS應用程式有哪些關鍵物件以及它們職責主要是什麼?

The Structure of an App.png

  • UIApplication物件 使用者與iOS裝置互動時產生的事件(Multitouch Events,Motion Event,Remote Control Event)交由UIApplication物件來分發給control objects(UIControl)對應的target objects來處理並且管理整個事件迴圈,而一些關於app執行時重要事件委託給app delegate來處理。
  • App delegate物件 App delegate物件遵循UIApplicationDelegate協議,響應app執行時重要事件(app啟動、app記憶體不足、app終止、切換到另一個app、切回app),主要用於app在啟動時初始化一些重要資料結構;例如,初始化UIWindow,設定一些屬性,為window新增rootViewController。
  • View controller物件 View Controller有一個view屬性是view層次結構中的根view,你可以新增子view來構建複雜的view;controller有一些viewDidLoad、viewWillAppear等方法來管理view的生命週期;由於它繼承UIResponder,所有還會響應和處理使用者事件。
  • Documents和data model物件 data model物件主要用來儲存資料。例如,餓了麼app在搜尋切換地址後,有歷史記錄搜尋地址歷史,當app下次啟動時,讀取和顯示搜尋地址歷史。 document物件(繼承UIDocument)用來管理一些或所有的data model物件。document物件並不是必須的,但提供一種方便的方式來分組屬於單個檔案或多個檔案的資料。
  • UIWindow物件 UIWindow物件位於view層次結構中的最頂層,它充當一個基本容器而不顯示內容,如果想顯示內容,新增一個content view到window。 它也是繼承UIResponder,所以它也是會響應和處理使用者事件。
  • Viewcontrollayer物件 View物件可以通過addSubview和removeFromSuperview 等方法管理view的層次結構,使用layoutSubviews、layoutIfNeeded和setNeedsLayout等方法佈局view的層次結構,當你發現系統提供view已經滿足不了你想要的外觀需求時,可以重寫drawRect方法或通過layer屬性來構造複雜的圖形外觀和動畫。還有一點,UIView也是繼承UIResponder,所以也能夠處理使用者事件。 Control物件通常就是處理特定型別使用者互動的View,常用的有button、switch、text field等。 除了使用View和Control來構建view層次結構來影響app外觀之外,還可以使用Core Animation框架的Layer物件來渲染view外觀和構建複雜的動畫。

Main Run Loop

一個iOS應用程式的main run loop主要作用是處理所有與使用者相關的事件。UIApplication物件在啟動時就設定main run loop和使用它來處理事件和更新基於view的介面。正如它的名字顯示,main run loop是執行在應用程式的主執行緒。這樣就確保與接收到使用者相關的事件被有序地處理。

下圖顯示main run loop的架構和使用者事件最終是怎樣被應用程式處理。當用戶與裝置互動時,系統就會生成與互動關聯的事件,然後被應用程式的UIKit通過一個特殊的埠來分發。應用程式把事件放入佇列,然後逐個分發到main run loop來執行。UIApplication物件是第一個物件接收到事件,然後決定怎樣處理它。一個touch event通常都被分發到main window物件,然後依次分發到發生觸碰的view。其他event的接收事件物件路徑可能有點不同。

大多數的事件通過使用main run loop來分發,但有些不是。有些事件被髮送到一個delegate物件或傳遞到你提供的block中。想了解更多如何處理大多數型別的事件,其中包括touch、remote control、motion、accelerometer和gyroscopic等事件,請查閱Event Handle Guide for iOS