iOS開發 APP啟動過程

GabrielPanda發表於2018-01-25

當使用者點選應用圖示之後,應用就開始啟動。應用啟動完成後,就會展示一系列的檢視,和使用者進行各種各樣的互動(如滑動、點選)。當使用者退出應用後,該應用就無法和使用者進行互動。這一過程就體現了一個應用的生命週期(從啟動到退出)。這裡只介紹應用程式的顯示部分。

在介紹應用啟動過程及原理之前,先來了解一些概念以及其作用。

1、UIApplication

UIApplication物件是應用程式的象徵,一個UIApplication物件就代表一個應用程式。每一個應用都有自己的UIApplication物件,而且是單例的,如果試圖在程式中新建一個UIApplication物件,那麼將報錯提示。一個iOS程式啟動後建立的第一個物件就是UIApplication物件,且只有一個。利用UIApplication物件,能進行一些應用級別的操作。可以參考[iOS開發之UIApplication和delegate](http://blog.csdn.net/shxwork/article/details/50053489)

2、UIApplication Delegate

   所有的移動作業系統都有個問題:APP很容易受到打擾。比如來電或者鎖屏會導致APP進入後臺甚至被終止。還有很多其它類似的情況會導致app受到干擾,在app受到干擾時,會產生一些系統事件,這時UIApplication會通知它的delegate物件,讓delegate代理來處理這些系統事件。
  UIApplication Delegate的作用是當應用程式發出一系列系統事件時,做出相應的反應。新建完專案,都有個帶有“AppDelegate”字眼的類,它就是UIApplication的代理,AppDelegate預設已經遵守了UIApplicationDelegate協議,已經是UIApplication的代理。系統事件如程式降將要啟動、程式啟動完成、程式進入後臺、程式進入前臺、程式退出等。對應代理的方法如下:
複製程式碼
/** 
 *  程式啟動完成 
 */  
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 {  
    return YES;  
}  
/** 
 *  程式將要進入後臺 
 */  
- (void)applicationWillResignActive:(UIApplication *)application 
{  }  
  
/** 
 *  程式進入後臺 
 */  
- (void)applicationDidEnterBackground:(UIApplication *)application 
{   }  
  
/** 
 *  程式將要進入前臺 
 */  
- (void)applicationWillEnterForeground:(UIApplication *)application 
{  }  
  
/** 
 *  程式進入前臺 
 */  
- (void)applicationDidBecomeActive:(UIApplication *)application
{  }  
  
/** 
 *  程式退出 
 */  
- (void)applicationWillTerminate:(UIApplication *)application 
{  } 

複製程式碼

上面就是涉及到應用程式非常重要的兩個概念,下面我們來介紹點選應用圖示後,應用程式的啟動。我們都知道,C語言是從main函式開始執行程式碼的。OC作為C語言的超集,當然也不例外。點選圖示,開始執行main函式。iOS專案中的main函式是在建立專案的時候就已經寫好了的,如下:

 @autoreleasepool {  
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));  
    } 
複製程式碼

UIApplicationMain函式引數 可以看到iOS專案中的main函式執行了一個UIApplicationMain函式,所有我們的重點就是要連線UIApplicationMain在執行的時候都做了哪些事情。下面我們先來了解一下UIApplicationMain函式的引數

 *  @param argc   系統引數 
 *  @param argv   系統引數 
 *  @param nil    應用程式名稱 
 *  @param class] 應用程式代理名稱 
 */  
UIApplicationMain(int argc, charchar *argv[], NSString *principalClassName, NSString *delegateClassName);
複製程式碼

argc、argv:直接傳遞給UIApplicationMain進行相關處理即可 principalClassName:指定應用程式類名(app的象徵),該類必須是UIApplication(或子類)。如果為nil,則用UIApplication類作為預設值 delegateClassName:指定應用程式的代理類,該類必須遵守UIApplicationDelegate協議

UIApplicationMain函式作用 main函式中之是執行了UIApplicationMain函式,可以肯定的時候該函式一定很重要,但它的具體作用是什麼呢, UIApplicationMain函式會根據principalClassName建立UIApplication物件,根據delegateClassName建立一個delegate物件,並將該delegate物件賦值給UIApplication物件中的delegate屬性 。 接著會建立應用程式的Main Runloop(事件迴圈),進行事件的處理(首先會在程式完畢後呼叫delegate物件的application:didFinishLaunchingWithOptions:方法)。 app啟動時會載入Info.plist檔案,看是否指定了main.storyboard,如果設定了就去載入main.storyboard,那麼載入main.storyboard時,系統會進行如下操作: 建立視窗 -> 載入main.storyboard並且載入main.storyboard中指定的控制器 -> 建立控制器成為視窗的根控制器,讓視窗顯示出來。

總結UIApplicationMain函式作用: argc:系統或者使用者傳入的引數 argv:系統或使用者傳入的實際引數 1.根據傳入的第三個引數,建立UIApplication物件 2.根據傳入的第四個產生建立UIApplication物件的代理 3.設定剛剛建立出來的代理物件為UIApplication的代理 4.開啟一個事件迴圈(可以理解為裡面是一個死迴圈)這個時間迴圈是一個佇列(先進先出)先新增進去的先處理 5.載入Info.plist檔案,看是否指定了main.storyboard,如果設定了就去載入main.storyboard

3、UIWindow的建立

   UIWindow  是特殊的 UIView ,通常一個App中只有UIWindows,當程式啟動完畢後,建立的第一個檢視控制元件就是UIWindow,接著建立控制器的UIView,將控制器的View新增到UIWindow上,控制器的 UIView 就顯示在螢幕上。注意 UIWindow 本身不做顯示,是控制器的UIView做展示,UIWindow 會給檢視分發事件。
   如果應用程式設定了main.storyboard檔案,並指定了初始化控制器,系統會自動建立UIWindow。如果沒有指定main.storyboard檔案,就必須手動去建立。
複製程式碼

UIWindow作用: 1.UIWindow作為一個容器,容納所有的UIView 2.UIWindow會其他事件訊息傳遞給UIWiew

4、控制器的建立

當UIWindow建立完成後,必須指定一個根控制器或者在UIWIndow上新增子檢視,這樣才能顯示出來,使用者才能看得到,因為前面提到過,UIWindow本身不做顯示。當指定了UIWindow的根控制器,該控制器的view會自動新增在UIWindow上,並顯示出來。控制器的建立可以看這篇文章

5、檢視控制器view的建立

檢視控制器就是控制器檢視在螢幕上的顯示,對於一個控制器來說也是不具備顯示的,只有它的view才具有顯示能力,所以建立完一個控制器的時候,要給它指定一個根檢視。具體的控制器view的建立可以檢視這篇文章

6、應用程式的狀態

應用程式到這裡就可以顯示了。根據前面的應用程式代理功能的介紹,應用程式在啟動過程中有以下幾種狀態:

  1. Not running :應用還沒有啟動,或者應用正在執行但是途中被系統停止。
  2. Inactive :當前應用正在前臺執行,但是並不接收事件(當前 或許正在執行其它程式碼)。一般每當應用要從一個狀態切換到另一個不同的狀態時,中途過渡會短暫停留在此狀態。唯一在此狀態停留時間比較長的情況是:當使用者 鎖屏時,或者系統提示使用者去響應某些(諸如電話來電、有未讀簡訊等)事件的時候。
  3. Active :當前應用正在前臺執行,並且接收事件。這是應用正在前臺執行時所處的正常狀態。
  4. Background :應用處在後臺,並且還在執行程式碼。大多數將 要進入Suspended狀態的應用,會先短暫進入此狀態。然而,對於請求需要額外的執行時間的應用,會在此狀態保持更長一段時間。另外,如果一個應用要 求啟動時直接進入後臺執行,這樣的應用會直接從Not running狀態進入Background狀態,中途不會經過Inactive狀態。比如沒有介面的應用。注此處並不特指沒有介面的應用,其實也可以是 有介面的應用,只是如果要直接進入background狀態的話,該應用介面不會被顯示。
  5. Suspended :應用處在後臺,並且已停止執行程式碼。系統自動 的將應用移入此狀態,且在此舉之前不會對應用做任何通知。當處在此狀態時,應用依然駐留記憶體但不執行任何程式程式碼。當系統發生低記憶體告警時,系統將會將處 於Suspended狀態的應用清除出記憶體以為正在前臺執行的應用提供足夠的記憶體。

五種狀態.png

相關文章