序言
?????? 當(dāng)用戶點擊應(yīng)用圖標(biāo)之后,應(yīng)用就開始啟動撬讽。應(yīng)用啟動完成后蕊连,就會展示一系列的視圖,和用戶進(jìn)行各種各樣的交互(如滑動游昼、點擊)咪奖。當(dāng)用戶退出應(yīng)用后,該應(yīng)用就無法和用戶進(jìn)行交互酱床。這一過程就體現(xiàn)了一個應(yīng)用的生命周期(從啟動到退出)。這里只介紹應(yīng)用程序的顯示部分趟佃。
?????? 在介紹應(yīng)用啟動過程及原理之前扇谣,先來了解一些概念以及其作用。
1闲昭、UIApplication
????? UIApplication對象是應(yīng)用程序的象征罐寨,一個UIApplication對象就代表一個應(yīng)用程序。每一個應(yīng)用都有自己的UIApplication對象序矩,而且是單例的鸯绿,如果試圖在程序中新建一個UIApplication對象,那么將報錯提示簸淀。一個iOS程序啟動后創(chuàng)建的第一個對象就是UIApplication對象瓶蝴,且只有一個。利用UIApplication對象租幕,能進(jìn)行一些應(yīng)用級別的操作舷手。
UIApplication對象是應(yīng)用程序的象征
1.每一個應(yīng)用都有自己的UIApplication對象,而且是單例的.????????????????????????????????????????????????????????????????????????????????2.通過[UIApplication sharedApplication]可以獲得這個單例對象.????????????????????????????????????????????????????????????????????????3.一個iOS程序啟動后創(chuàng)建的第一個對象就是UIApplication對象????????????????????????????????????????????????????????????????????????4.利用UIApplication對象劲绪,能進(jìn)行一些應(yīng)用級別的操作
作用:
設(shè)置應(yīng)用程序圖標(biāo)右上角的紅色提醒數(shù)字 ?
`@property(nonatomic)NSInteger applicationIconBadgeNumber;`
設(shè)置聯(lián)網(wǎng)指示器的可見性?
`@property(nonatomic,getter=isNetworkActivityIndicatorVisible)BOOL networkActivityIndicatorVisible;`
在iOS7中男窟,默認(rèn)情況下盆赤,狀態(tài)欄都是由UIViewController管理的,UIViewController實現(xiàn)下列方法就可以輕松管理狀態(tài)欄的可見性和樣式
狀態(tài)欄的樣式:- (UIStatusBarStyle)preferredStatusBarStyle;
狀態(tài)欄的可見性:- (BOOL)prefersStatusBarHidden;
openURL:(UIApplication很重要的方法):
UIApplication有個功能十分強(qiáng)大方法:- (BOOL)openURL:(NSURL*)url;
openURL:方法的部分功能有
打電話
UIApplication *app = [UIApplication sharedApplication];
[app openURL:[NSURL URLWithString:@"tel://10086"]];
發(fā)短信
[app openURL:[NSURL URLWithString:@"sms://15011230980"]];
發(fā)郵件
[app openURL:[NSURL URLWithString:@"mailto://user@163.com"]];
打開一個網(wǎng)頁資源
[app openURL:[NSURL URLWithString:@"http://www.baidu.com"]];
打開其他app程序 注意:URL:是一種資源的唯一路徑(任何一種資源都可以由資源的唯一路徑找到)歉眷。由三部分組成:協(xié)議://主機(jī)域名/路徑.
轉(zhuǎn)自:這兒
2牺六、UIApplication Delegate
?????? 所有的移動操作系統(tǒng)都有個致命的缺點:app很容易受到打擾。比如一個來電或者鎖屏?xí)?dǎo)致app進(jìn)入后臺甚至被終止汗捡。還有很多其它類似的情況會導(dǎo)致app受到干擾淑际,在app受到干擾時,會產(chǎn)生一些系統(tǒng)事件凉唐,這時UIApplication會通知它的delegate對象庸追,讓delegate代理來處理這些系統(tǒng)事件。
????? 所有UIApplication Delegate的作用是當(dāng)應(yīng)用程序發(fā)出一系列系統(tǒng)事件時台囱,做出相應(yīng)的反應(yīng)淡溯。每次新建完項目,都有個帶有“AppDelegate”字眼的類簿训,它就是UIApplication的代理,AppDelegate默認(rèn)已經(jīng)遵守了UIApplicationDelegate協(xié)議咱娶,已經(jīng)是UIApplication的代理。系統(tǒng)事件如程序降將要啟動强品、程序啟動完成膘侮、程序進(jìn)入后臺、程序進(jìn)入前臺的榛、程序退出等琼了。對應(yīng)代理的方法如下:
*? 程序啟動完成
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
?? ?return YES;
}
*? 程序?qū)⒁M(jìn)入后臺
- (void)applicationWillResignActive:(UIApplication *)application {
}
*? 程序進(jìn)入后臺
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
*? 程序?qū)⒁M(jìn)入前臺
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
*? 程序進(jìn)入前臺
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
*? 程序退出
- (void)applicationWillTerminate:(UIApplication *)application {
}
【正文】
1.點擊圖標(biāo),開始執(zhí)行main函數(shù)夫晌。
iOS項目中的main函數(shù)是在創(chuàng)建項目的時候就已經(jīng)寫好了的雕薪,可以看到iOS項目中的main函數(shù)執(zhí)行了一個UIApplicationMain函數(shù),所有我們的重點就是要連接UIApplicationMain在執(zhí)行的時候都做了哪些事情晓淀。
下面我們先來了解一下UIApplicationMain函數(shù)的參數(shù)
<span style="font-size:14px;">/**
*? @param argc? 系統(tǒng)參數(shù)
*? @param argv? 系統(tǒng)參數(shù)
*? @param nil? ? 應(yīng)用程序名稱
*? @param class] 應(yīng)用程序代理名稱
*/
UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);</span>
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ù)一定很重要懦窘,但它的具體作用是什么呢前翎,
? ? ?1.創(chuàng)建UIApplication對象以及delegate?
?UIApplicationMain函數(shù)會根據(jù)principalClassName創(chuàng)建UIApplication對象,根據(jù)delegateClassName創(chuàng)建一個delegate對象畅涂,并將該delegate對象賦值給UIApplication對象中的delegate屬性 鱼填。
? ? ?2.建立main runloop ?
接著會建立應(yīng)用程序的Main Runloop(事件循環(huán)),進(jìn)行事件的處理(首先會在程序完畢后調(diào)用delegate對象的application:didFinishLaunchingWithOptions:方法)毅戈。
?????? app啟動時會加載Info.plist文件苹丸,看是否指定了main.storyboard愤惰,如果設(shè)置了就去加載main.storyboard,那么加載main.storyboard時赘理,系統(tǒng)會進(jìn)行如下操作:
?????? 創(chuàng)建窗口 -> 加載main.storyboard并且加載main.storyboard中指定的控制器 -> 創(chuàng)建控制器成為窗口的根控制器宦言,讓窗口顯示出來。
總結(jié)UIApplicationMain函數(shù)作用:
argc:系統(tǒng)或者用戶傳入的參數(shù)
argv:系統(tǒng)或用戶傳入的實際參數(shù)?
1.根據(jù)傳入的第三個參數(shù)商模,創(chuàng)建UIApplication對象
2.根據(jù)傳入的第四個產(chǎn)生創(chuàng)建UIApplication對象的代理
3.設(shè)置剛剛創(chuàng)建出來的代理對象為UIApplication的代理
4.開啟一個事件循環(huán)(可以理解為里面是一個死循環(huán))這個時間循環(huán)是一個隊列(先進(jìn)先出)先添加進(jìn)去的先處理
5.加載Info.plist文件奠旺,看是否指定了main.storyboard,如果設(shè)置了就去加載main.storyboard
3.UIWindow的創(chuàng)建
?????? UIWindow ?是特殊的 UIView ,通常一個App中只有UIWindows施流,當(dāng)程序啟動完畢后响疚,創(chuàng)建的第一個視圖控件就是UIWindow,接著創(chuàng)建控制器的UIView,將控制器的View添加到UIWindow上,控制器的 UIView 就顯示在屏幕上瞪醋。注意 UIWindow 本身不做顯示忿晕,是控制器的UIView做展示,UIWindow 會給視圖分發(fā)事件银受。
?????? 如果應(yīng)用程序設(shè)置了main.storyboard文件践盼,并指定了初始化控制器,系統(tǒng)會自動創(chuàng)建UIWindow宾巍。如果沒有指定main.storyboard文件咕幻,就必須手動去創(chuàng)建。
UIWindow作用:
1.UIWindow作為一個容器顶霞,容納所有的UIView
2.UIWindow會其他事件消息傳遞給UIWiew
4肄程、控制器的創(chuàng)建
????????當(dāng)UIWindow創(chuàng)建完成后,必須指定一個根控制器或者在UIWIndow上添加子視圖选浑,這樣才能顯示出來蓝厌,用戶才能看得到,因為前面提到過鲜侥,UIWindow本身不做顯示。當(dāng)指定了UIWindow的根控制器诸典,該控制器的view會自動添加在UIWindow上描函,并顯示出來。
5狐粱、視圖控制器view的創(chuàng)建
?????? 視圖控制器就是控制器視圖在屏幕上的顯示舀寓,對于一個控制器來說也是不具備顯示的,只有它的view才具有顯示能力肌蜻,所以創(chuàng)建完一個控制器的時候互墓,要給它指定一個根視圖。
6蒋搜、應(yīng)用程序的狀態(tài)
應(yīng)用程序到這里就可以顯示了篡撵。根據(jù)前面的應(yīng)用程序代理功能的介紹判莉,應(yīng)用程序在啟動過程中有以下幾種狀態(tài):
1. Not running :應(yīng)用還沒有啟動,或者應(yīng)用正在運行但是途中被系統(tǒng)停止育谬。
2. Inactive :當(dāng)前應(yīng)用正在前臺運行券盅,但是并不接收事件(當(dāng)前 或許正在執(zhí)行其它代碼)。一般每當(dāng)應(yīng)用要從一個狀態(tài)切換到另一個不同的狀態(tài)時膛檀,中途過渡會短暫停留在此狀態(tài)锰镀。唯一在此狀態(tài)停留時間比較長的情況是:當(dāng)用戶 鎖屏?xí)r,或者系統(tǒng)提示用戶去響應(yīng)某些(諸如電話來電咖刃、有未讀短信等)事件的時候泳炉。
3. Active :當(dāng)前應(yīng)用正在前臺運行,并且接收事件嚎杨。這是應(yīng)用正在前臺運行時所處的正常狀態(tài)花鹅。
4. Background :應(yīng)用處在后臺,并且還在執(zhí)行代碼磕潮。大多數(shù)將 要進(jìn)入Suspended狀態(tài)的應(yīng)用翠胰,會先短暫進(jìn)入此狀態(tài)。然而自脯,對于請求需要額外的執(zhí)行時間的應(yīng)用之景,會在此狀態(tài)保持更長一段時間。另外膏潮,如果一個應(yīng)用要 求啟動時直接進(jìn)入后臺運行锻狗,這樣的應(yīng)用會直接從Not running狀態(tài)進(jìn)入Background狀態(tài),中途不會經(jīng)過Inactive狀態(tài)焕参。比如沒有界面的應(yīng)用轻纪。注此處并不特指沒有界面的應(yīng)用,其實也可以是 有界面的應(yīng)用叠纷,只是如果要直接進(jìn)入background狀態(tài)的話刻帚,該應(yīng)用界面不會被顯示。
5. Suspended :應(yīng)用處在后臺涩嚣,并且已停止執(zhí)行代碼崇众。系統(tǒng)自動 的將應(yīng)用移入此狀態(tài),且在此舉之前不會對應(yīng)用做任何通知航厚。當(dāng)處在此狀態(tài)時顷歌,應(yīng)用依然駐留內(nèi)存但不執(zhí)行任何程序代碼。當(dāng)系統(tǒng)發(fā)生低內(nèi)存告警時幔睬,系統(tǒng)將會將處 于Suspended狀態(tài)的應(yīng)用清除出內(nèi)存以為正在前臺運行的應(yīng)用提供足夠的內(nèi)存眯漩。
下面是這五種狀態(tài)在實際中的切換圖: