iOS程序啟動原理的理解
應用的生命周期(從啟動到退出):當用戶點擊應用圖標之後,應用就開始啟動。應用啟動完成後,就會展示一系列的視圖,和用戶進行各種各樣的交互(如滑動、點擊)。當用戶退出應用後,該應用就無法和用戶進行交互。這一過程就是應用的生命周期體現。
在介紹應用啟動過程及原理之前,先來了解一些概念以及其作用。
1、UIApplication
UIApplication對象是應用程序的象征,一個UIApplication對象就代表一個應用程序。每一個應用都有自己的UIApplication對象,而且是單例的,如果試圖在程序中新建一個UIApplication對象,那麽將報錯提示。一個iOS
2、UIApplication Delegate
所有的移動操作系統都有個致命的缺點:app很容易受到打擾。比如一個來電或者鎖屏會導致app進入後臺甚至被終止。還有很多其它類似的情況會導致app受到幹擾,在app受到幹擾時,會產生一些系統事件(iOS系統處理系統的事件的有限級別高於處理某個程序的事件),這時UIApplication會通知它的delegate對象,讓delegate代理來處理這些系統事件。
所有UIApplicationDelegate的代理作用是當應用程序發出一系列系統事件時,做出相應的反應,也就是監聽應用程序的狀態變化如:進入、退出、程序間的調轉
- /**
- * 程序啟動完成:各個類加載完畢
- */
- - (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函數是在創建項目的時候就已經寫好了的,如下:
int main(int argc, char * argv[]) {
@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);</span>
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狀態的應用清除出內存以為正在前臺運行的應用提供足夠的內存。
iOS程序啟動原理的理解