iOS 應用程序生命週期中那些不可忽視的“存在”

開發過Android應用的程序員都知道Android應用的生命週期更多是其組件的生命週期,例如Activity、Service。那麼iOS應用程序的生命週期是怎樣的呢?今天我們首先簡單來了解一下。


iOS應用程序一般都是由自己編寫的代碼和系統框架(system frameworks)組成,系統框架提供一些基本infrastructure給所有app來運行,而自己編寫的代碼主要是根據需求來定製app的外觀和行爲的。


iOS的程序入口在main.m文件:


#import

#import "AppDelegate.h"

 

int main(int argc, char * argv[])

{

    @autoreleasepool {

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

    }

}



我們可以看到在上面的代碼中有一個很重要的函數—— UIApplicationMain,它的作用主要是創建app的幾個核心對象來處理以下過程:


(1)從可用Storyboard文件加載用戶界面

(2)調用AppDelegate自定義代碼來做一些初始化設置

(3)將app放入Main Run Loop環境中來響應和處理與用戶交互產生的事件


 UIApplicationMain函數,重點是後兩個參數,分別表示程序的主要類(principal class)和代理類(delegate class)。如果主要類(principal class)爲nil,將從Info.plist中獲取,如果Info.plist中不存在對應的key,則默認爲UIApplication;而代理類(delegate class)將在新建工程時創建。


根據UIApplicationMain函數,程序將進入AppDelegate.m,這個文件是xcode新建工程時自動生成的。AppDelegate.m文件有關乎着應用程序的生命週期的方法。

應用程序的狀態有以下幾種:

  • Not running:app還沒運行

  • Inactive:app運行在foreground但沒有接收事件

  • Active:app運行在foreground和正在接收事件

  • Background:運行在background和正在執行代碼

  • Suspended:運行在background但沒有執行代碼


切換狀態如圖所示:



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


1、application didFinishLaunchingWithOptions:當應用程序啓動時執行,應用程序啓動入口,只在應用程序啓動時執行一次。若用戶直接啓動,lauchOptions內無數據,若通過其他方式啓動應用,lauchOptions包含對應方式的內容。

 2、applicationWillResignActive:在應用程序將要由活動狀態切換到非活動狀態時候,要執行的委託調用,如 按下 home 按鈕,返回主屏幕,或全屏之間切換應用程序等。

 3、applicationDidEnterBackground:在應用程序已進入後臺程序時,要執行的委託調用。

 4、applicationWillEnterForeground:在應用程序將要進入前臺時(被激活),要執行的委託調用,剛好與applicationWillResignActive 方法相對應。

 5、applicationDidBecomeActive:在應用程序已被激活後,要執行的委託調用,剛好與applicationDidEnterBackground 方法相對應。

 6、applicationWillTerminate:在應用程序要完全推出的時候,要執行的委託調用,這個需要要設置UIApplicationExitsOnSuspend的鍵值。 


應用程序的架構


相信大家都很熟悉MVC,iOS應用程序現在大多都遵循Model-View-Controller的架構。


Model負責存儲數據和處理業務邏輯,View負責顯示數據和與用戶交互,Controller是兩者的中介,協調Model和View相互協作。(點擊查看 Model數據層解析Controller邏輯層解析


它們的通訊規則如下:


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



當View與用戶交互產生事件時,使用target-action方式來處理



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



Model不能直接與Controller通信,當Model有數據更新時,可以通過Notification或KVO (Key Value Observing)來通知Controller更新View。



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


  • UIApplication對象



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

UIApplication的核心作用是提供了iOS程序運行期間的控制和協作工作。用戶與iOS設備交互時產生的事件(Multitouch Events,Motion Event,Remote Control Event)交由UIApplication對象來分發給control objects(UIControl)對應的target objects來處理並且管理整個事件循環也就是當需要處理用戶事件時,它會起一個隊列,把所有用戶事件都放入隊列,逐個處理,在處理的時候,它會發送當前事件 到一個合適的處理事件的目標控件。而一些關於app運行時重要事件委託給app delegate來處理(點擊查看 UIApplication詳情)


  • App delegate對象



實際上App delegate是遵循了UIApplicationDelegate協議的類,UIApplicationDelegate協議定義了很多和Application狀態、消息相關的方法。您可以簡單的理解爲Application和系統的一個聯繫。在創建project的時候,Xcode會自動爲您生成一個AppDelegate類。並在程序運行起來的時候創建AppDelegate對象(方式是通過UIApplicationMain的方法,在main.m文件中,這個就是App的入口函數)。這樣在App運行過程中,就會調用AppDelegate中的方法。它響應app運行時重要事件(app啓動、app內存不足、app終止、切換到另一個app、切回app),主要用於app在啓動時初始化一些重要數據結構;例如,初始化UIWindow,設置一些屬性,爲window添加rootViewController。


  • View controller對象

3

viewController,是Xcode爲您提供的一個視圖控制器。您可以在其中實現相關的邏輯。View Controller有一個view屬性是view層次結構中的根view,你可以添加子view來構建複雜的view;controller有一些viewDidLoad、viewWillAppear等方法來管理view的生命週期;由於它繼承UIResponder,所有還會響應和處理用戶事件。


  • UIWindow對象

4

UIWindow類是UIView的子類,可以看作是特殊的UIView。UIWindow對象是所有UIView的根視圖,管理和協調的應用程序的顯示、分發事件給View。它位於view層次結構中的最頂層,它充當一個基本容器而不顯示內容,如果想顯示內容,添加一個content view到window。它繼承UIResponder,所以會響應和處理用戶事件。一般應用程序只有一個UIWindow對象,即使有多個UIWindow對象,也只有一個UIWindow可以接受到用戶的觸屏事件。UIWindow初始化在appDeleDgate裏面的 didFinishLaunchingWithOptions方法。


  • View對象

5
View對象可以通過addSubview和removeFromSuperview 等方法管理view的層次結構,使用layoutIfNeeded和setNeedsLayout等方法佈局view的層次結構,當你發現系統提供view已經滿足不了你想要的外觀需求時,可以重寫drawRect方法或通過layer屬性來構造複雜的圖形外觀和動畫。還有一點,UIView也是繼承UIResponder,所以也能夠處理用戶事件。


  • Control、Layer對象

6

Control對象通常就是處理特定類型用戶交互的View,常用的有button、switch、text field等。

如果我們想要構建view層次結構來影響app外觀的話,除了view和control對象,還可以使用Core Animation框架的Layer對象來渲染view外觀和構建複雜的動畫。

UIKit中的控件包含了layer這個屬性,對於view來說,它是其用來存儲視圖屬性值的對象,我們對它進行動畫操作時,改變了視圖的屬性值,layer將這些改變傳遞給硬件,硬件再進行繪圖,相比於drawrect,它能夠有效的減輕CPU的負荷。


  • Responder

7

Responder是UIKit框架封裝的一個對象類型,它可以響應並處理事件。所有Responder對象的基類都是UIResponder。

下面我們來通過一張類圖看看哪些對象具有Responder特性





從上圖可以看出,UIApplication、UIViewController和UIView都是UIResponder對象,都具有對事件進行響應,處理的能力。


  • Main Run Loop

8

main run loop是運行在應用程序的主線程。主要作用是處理所有與用戶相關的事件,確保接收到用戶相關的事件能夠被有序地處理。UIApplication對象在啓動時就設置main run loop和使用它來處理事件和更新基於view的界面。

下圖是main run loop的架構和用戶事件被應用程序處理的過程。




當用戶與設備交互時,系統就會生成與交互關聯的事件,然後被應用程序的UIKit通過一個特殊的端口來分發。應用程序把事件放入隊列,然後逐個分發到main run loop來執行。UIApplication對象是第一個對象接收到事件,然後決定怎樣處理它。一個touch event通常都被分發到main window對象,然後依次分發到發生觸碰的view。其他event的接收事件對象路徑可能有點不同,大家可以深入瞭解一下事件傳遞這個過程,會對此有比較深刻的理解。(點擊查看事件傳遞詳情)。


總結:


本文簡單總結了iOS應用程序從啓動到結束過程中有哪些關鍵對象在參與,以及相關的內容,希望能給大家帶來些許幫助!

發佈了15 篇原創文章 · 獲贊 12 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章