iOS開(kāi)發(fā)-APP啟動(dòng)過(guò)程

當(dāng)用戶點(diǎn)擊應(yīng)用圖標(biāo)之后,應(yīng)用就開(kāi)始啟動(dòng)。應(yīng)用啟動(dòng)完成后,就會(huì)展示一系列的視圖,和用戶進(jìn)行各種各樣的交互(如滑動(dòng)、點(diǎn)擊)。當(dāng)用戶退出應(yīng)用后,該應(yīng)用就無(wú)法和用戶進(jìn)行交互。這一過(guò)程就體現(xiàn)了一個(gè)應(yīng)用的生命周期(從啟動(dòng)到退出)。這里只介紹應(yīng)用程序的顯示部分。

在介紹應(yīng)用啟動(dòng)過(guò)程及原理之前,先來(lái)了解一些概念以及其作用。

1、UIApplication

  UIApplication對(duì)象是應(yīng)用程序的象征,一個(gè)UIApplication對(duì)象就代表一個(gè)應(yīng)用程序。每一個(gè)應(yīng)用都有自己的UIApplication對(duì)象,而且是單例的,如果試圖在程序中新建一個(gè)UIApplication對(duì)象,那么將報(bào)錯(cuò)提示。一個(gè)iOS程序啟動(dòng)后創(chuàng)建的第一個(gè)對(duì)象就是UIApplication對(duì)象,且只有一個(gè)。利用UIApplication對(duì)象,能進(jìn)行一些應(yīng)用級(jí)別的操作。可以參考[[iOS開(kāi)發(fā)之UIApplication和delegate](http://blog.csdn.net/shxwork/article/details/50053489)](http://blog.csdn.net/shxwork/article/details/50053489)

2、UIApplication Delegate

   所有的移動(dòng)操作系統(tǒng)都有個(gè)問(wèn)題:APP很容易受到打擾。比如來(lái)電或者鎖屏?xí)?dǎo)致APP進(jìn)入后臺(tái)甚至被終止。還有很多其它類似的情況會(huì)導(dǎo)致app受到干擾,在app受到干擾時(shí),會(huì)產(chǎn)生一些系統(tǒng)事件,這時(shí)UIApplication會(huì)通知它的delegate對(duì)象,讓delegate代理來(lái)處理這些系統(tǒng)事件。
  UIApplication Delegate的作用是當(dāng)應(yīng)用程序發(fā)出一系列系統(tǒng)事件時(shí),做出相應(yīng)的反應(yīng)。新建完項(xiàng)目,都有個(gè)帶有“AppDelegate”字眼的類,它就是UIApplication的代理,AppDelegate默認(rèn)已經(jīng)遵守了UIApplicationDelegate協(xié)議,已經(jīng)是UIApplication的代理。系統(tǒng)事件如程序降將要啟動(dòng)、程序啟動(dòng)完成、程序進(jìn)入后臺(tái)、程序進(jìn)入前臺(tái)、程序退出等。對(duì)應(yīng)代理的方法如下:
/** 
 *  程序啟動(dòng)完成 
 */  
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 {  
    return YES;  
}  
/** 
 *  程序?qū)⒁M(jìn)入后臺(tái) 
 */  
- (void)applicationWillResignActive:(UIApplication *)application 
{  }  
  
/** 
 *  程序進(jìn)入后臺(tái) 
 */  
- (void)applicationDidEnterBackground:(UIApplication *)application 
{   }  
  
/** 
 *  程序?qū)⒁M(jìn)入前臺(tái) 
 */  
- (void)applicationWillEnterForeground:(UIApplication *)application 
{  }  
  
/** 
 *  程序進(jìn)入前臺(tái) 
 */  
- (void)applicationDidBecomeActive:(UIApplication *)application
{  }  
  
/** 
 *  程序退出 
 */  
- (void)applicationWillTerminate:(UIApplication *)application 
{  } 

上面就是涉及到應(yīng)用程序非常重要的兩個(gè)概念,下面我們來(lái)介紹點(diǎn)擊應(yīng)用圖標(biāo)后,應(yīng)用程序的啟動(dòng)。我們都知道,C語(yǔ)言是從main函數(shù)開(kāi)始執(zhí)行代碼的。OC作為C語(yǔ)言的超集,當(dāng)然也不例外。點(diǎn)擊圖標(biāo),開(kāi)始執(zhí)行main函數(shù)。iOS項(xiàng)目中的main函數(shù)是在創(chuàng)建項(xiàng)目的時(shí)候就已經(jīng)寫好了的,如下:

 @autoreleasepool {  
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));  
    } 

UIApplicationMain函數(shù)參數(shù)
可以看到iOS項(xiàng)目中的main函數(shù)執(zhí)行了一個(gè)UIApplicationMain函數(shù),所有我們的重點(diǎn)就是要連接UIApplicationMain在執(zhí)行的時(shí)候都做了哪些事情。下面我們先來(lái)了解一下UIApplicationMain函數(shù)的參數(shù)

 *  @param argc   系統(tǒng)參數(shù) 
 *  @param argv   系統(tǒng)參數(shù) 
 *  @param nil    應(yīng)用程序名稱 
 *  @param class] 應(yīng)用程序代理名稱 
 */  
UIApplicationMain(int argc, charchar *argv[], NSString *principalClassName, NSString *delegateClassName);

argc、argv:直接傳遞給UIApplicationMain進(jìn)行相關(guān)處理即可
principalClassName:指定應(yīng)用程序類名(app的象征),該類必須是UIApplication(或子類)。如果為nil,則用UIApplication類作為默認(rèn)值
delegateClassName:指定應(yīng)用程序的代理類,該類必須遵守UIApplicationDelegate協(xié)議

UIApplicationMain函數(shù)作用
main函數(shù)中之是執(zhí)行了UIApplicationMain函數(shù),可以肯定的時(shí)候該函數(shù)一定很重要,但它的具體作用是什么呢,
UIApplicationMain函數(shù)會(huì)根據(jù)principalClassName創(chuàng)建UIApplication對(duì)象,根據(jù)delegateClassName創(chuàng)建一個(gè)delegate對(duì)象,并將該delegate對(duì)象賦值給UIApplication對(duì)象中的delegate屬性 。
接著會(huì)建立應(yīng)用程序的Main Runloop(事件循環(huán)),進(jìn)行事件的處理(首先會(huì)在程序完畢后調(diào)用delegate對(duì)象的application:didFinishLaunchingWithOptions:方法)。
app啟動(dòng)時(shí)會(huì)加載Info.plist文件,看是否指定了main.storyboard,如果設(shè)置了就去加載main.storyboard,那么加載main.storyboard時(shí),系統(tǒng)會(huì)進(jìn)行如下操作:
創(chuàng)建窗口 -> 加載main.storyboard并且加載main.storyboard中指定的控制器 -> 創(chuàng)建控制器成為窗口的根控制器,讓窗口顯示出來(lái)。

總結(jié)UIApplicationMain函數(shù)作用:
argc:系統(tǒng)或者用戶傳入的參數(shù)
argv:系統(tǒng)或用戶傳入的實(shí)際參數(shù)
1.根據(jù)傳入的第三個(gè)參數(shù),創(chuàng)建UIApplication對(duì)象
2.根據(jù)傳入的第四個(gè)產(chǎn)生創(chuàng)建UIApplication對(duì)象的代理
3.設(shè)置剛剛創(chuàng)建出來(lái)的代理對(duì)象為UIApplication的代理
4.開(kāi)啟一個(gè)事件循環(huán)(可以理解為里面是一個(gè)死循環(huán))這個(gè)時(shí)間循環(huán)是一個(gè)隊(duì)列(先進(jìn)先出)先添加進(jìn)去的先處理
5.加載Info.plist文件,看是否指定了main.storyboard,如果設(shè)置了就去加載main.storyboard

3、UIWindow的創(chuàng)建

   UIWindow  是特殊的 UIView ,通常一個(gè)App中只有UIWindows,當(dāng)程序啟動(dòng)完畢后,創(chuàng)建的第一個(gè)視圖控件就是UIWindow,接著創(chuàng)建控制器的UIView,將控制器的View添加到UIWindow上,控制器的 UIView 就顯示在屏幕上。注意 UIWindow 本身不做顯示,是控制器的UIView做展示,UIWindow 會(huì)給視圖分發(fā)事件。
   如果應(yīng)用程序設(shè)置了main.storyboard文件,并指定了初始化控制器,系統(tǒng)會(huì)自動(dòng)創(chuàng)建UIWindow。如果沒(méi)有指定main.storyboard文件,就必須手動(dòng)去創(chuàng)建。

UIWindow作用:
1.UIWindow作為一個(gè)容器,容納所有的UIView
2.UIWindow會(huì)其他事件消息傳遞給UIWiew

4、控制器的創(chuàng)建

    當(dāng)UIWindow創(chuàng)建完成后,必須指定一個(gè)根控制器或者在UIWIndow上添加子視圖,這樣才能顯示出來(lái),用戶才能看得到,因?yàn)榍懊嫣岬竭^(guò),UIWindow本身不做顯示。當(dāng)指定了UIWindow的根控制器,該控制器的view會(huì)自動(dòng)添加在UIWindow上,并顯示出來(lái)??刂破鞯膭?chuàng)建可以看[這篇文章](http://blog.csdn.net/shxwork/article/details/50060645)

5、視圖控制器view的創(chuàng)建

   視圖控制器就是控制器視圖在屏幕上的顯示,對(duì)于一個(gè)控制器來(lái)說(shuō)也是不具備顯示的,只有它的view才具有顯示能力,所以創(chuàng)建完一個(gè)控制器的時(shí)候,要給它指定一個(gè)根視圖。具體的控制器view的創(chuàng)建可以查看[這篇文章](http://blog.csdn.net/shxwork/article/details/50065917)。

6、應(yīng)用程序的狀態(tài)

應(yīng)用程序到這里就可以顯示了。根據(jù)前面的應(yīng)用程序代理功能的介紹,應(yīng)用程序在啟動(dòng)過(guò)程中有以下幾種狀態(tài):

  1. Not running :應(yīng)用還沒(méi)有啟動(dòng),或者應(yīng)用正在運(yùn)行但是途中被系統(tǒng)停止。
  2. Inactive :當(dāng)前應(yīng)用正在前臺(tái)運(yùn)行,但是并不接收事件(當(dāng)前 或許正在執(zhí)行其它代碼)。一般每當(dāng)應(yīng)用要從一個(gè)狀態(tài)切換到另一個(gè)不同的狀態(tài)時(shí),中途過(guò)渡會(huì)短暫停留在此狀態(tài)。唯一在此狀態(tài)停留時(shí)間比較長(zhǎng)的情況是:當(dāng)用戶 鎖屏?xí)r,或者系統(tǒng)提示用戶去響應(yīng)某些(諸如電話來(lái)電、有未讀短信等)事件的時(shí)候。
  3. Active :當(dāng)前應(yīng)用正在前臺(tái)運(yùn)行,并且接收事件。這是應(yīng)用正在前臺(tái)運(yùn)行時(shí)所處的正常狀態(tài)。
  4. Background :應(yīng)用處在后臺(tái),并且還在執(zhí)行代碼。大多數(shù)將 要進(jìn)入Suspended狀態(tài)的應(yīng)用,會(huì)先短暫進(jìn)入此狀態(tài)。然而,對(duì)于請(qǐng)求需要額外的執(zhí)行時(shí)間的應(yīng)用,會(huì)在此狀態(tài)保持更長(zhǎng)一段時(shí)間。另外,如果一個(gè)應(yīng)用要 求啟動(dòng)時(shí)直接進(jìn)入后臺(tái)運(yùn)行,這樣的應(yīng)用會(huì)直接從Not running狀態(tài)進(jìn)入Background狀態(tài),中途不會(huì)經(jīng)過(guò)Inactive狀態(tài)。比如沒(méi)有界面的應(yīng)用。注此處并不特指沒(méi)有界面的應(yīng)用,其實(shí)也可以是 有界面的應(yīng)用,只是如果要直接進(jìn)入background狀態(tài)的話,該應(yīng)用界面不會(huì)被顯示。
  5. Suspended :應(yīng)用處在后臺(tái),并且已停止執(zhí)行代碼。系統(tǒng)自動(dòng) 的將應(yīng)用移入此狀態(tài),且在此舉之前不會(huì)對(duì)應(yīng)用做任何通知。當(dāng)處在此狀態(tài)時(shí),應(yīng)用依然駐留內(nèi)存但不執(zhí)行任何程序代碼。當(dāng)系統(tǒng)發(fā)生低內(nèi)存告警時(shí),系統(tǒng)將會(huì)將處 于Suspended狀態(tài)的應(yīng)用清除出內(nèi)存以為正在前臺(tái)運(yùn)行的應(yīng)用提供足夠的內(nèi)存。
五種狀態(tài).png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 關(guān)鍵步驟 一個(gè)程序從main函數(shù)開(kāi)始啟動(dòng)。代碼如下: int main(int argc, char * argv...
    JzRo閱讀 665評(píng)論 0 2
  • *面試心聲:其實(shí)這些題本人都沒(méi)怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來(lái)就是把...
    Dove_iOS閱讀 27,655評(píng)論 30 472
  • //聯(lián)系人:石虎QQ: 1224614774昵稱:嗡嘛呢叭咪哄 一、OC調(diào)用 C++會(huì)為靜態(tài)創(chuàng)建的對(duì)象生成初始化器...
    石虎132閱讀 2,745評(píng)論 0 19
  • 程序入口點(diǎn) 當(dāng)iOS app啟動(dòng)時(shí),系統(tǒng)會(huì)根據(jù)app bundle中的 Info.plist 文件中的 Execu...
    木板釘釘閱讀 3,563評(píng)論 2 9
  • 每個(gè)人內(nèi)心都有個(gè)柔軟的地方吧 大一會(huì)因?yàn)槌跹┮皇赘瓒聊瑴I流 那現(xiàn)在我的柔軟則是不可挽回的大學(xué)時(shí)光和青春 不知道從...
    calmalley閱讀 189評(píng)論 0 0

友情鏈接更多精彩內(nèi)容