UIApplication對(duì)象是應(yīng)用程序的象征
- 每一個(gè)應(yīng)用都有自己的UIApplication對(duì)象,而且是單例的
- 通過[UIApplication sharedApplication]可以獲得這個(gè)單例對(duì)象,命名規(guī)范一般單例都是使用shared拿到
- 一個(gè)iOS程序創(chuàng)建的第一個(gè)對(duì)象就是UIApplication對(duì)象
- 利用UIApplication對(duì)象,能進(jìn)行一些應(yīng)用級(jí)別操作
什么是單例?
整個(gè)應(yīng)用程序中只有一份,即只有一份內(nèi)存,并不會(huì)分配多余的內(nèi)存
新建項(xiàng)目,在ViewDidLoad中創(chuàng)建,會(huì)崩潰,原因?yàn)榧t色所圈部分
蘋果單例實(shí)現(xiàn):
1.內(nèi)部創(chuàng)建單例對(duì)象,程序啟動(dòng)的時(shí)創(chuàng)建該單例
2.提供一個(gè)方法,方便給外界獲取單例對(duì)象
3.外界不能調(diào)用alloc方法,一調(diào)用就會(huì)崩潰,即拋異常
模仿UIApplication單例對(duì)象的實(shí)現(xiàn),來更好的認(rèn)識(shí)UIApplication
1.創(chuàng)建一個(gè)CrabMan,通過重寫類方法load來模仿(類名隨意)項(xiàng)目一啟動(dòng)就創(chuàng)建對(duì)象。load方法會(huì)在程序一啟動(dòng)時(shí)自動(dòng)調(diào)用,將程序中所有的類加載出來,下圖為驗(yàn)證效果圖
2.創(chuàng)建并保存對(duì)象
創(chuàng)建完成后,使用靜態(tài)全局變量來保存,并聲明share方法供外部調(diào)用
疑問:為什么不用屬性來保存?
解答:因?yàn)閷傩允菍儆趯?duì)象的,在load方法對(duì)象還未創(chuàng)建完成,不能用對(duì)象的屬性來保存該對(duì)象本身。
疑問:為什么只在.m文件中實(shí)現(xiàn)load方法?
解答:我們demo的目的是演示UIApplication的單例,對(duì)象的創(chuàng)建在內(nèi)部進(jìn)行,獲取單例對(duì)象的方法提供給外部使用,該解答也回答了為什么shareCranMan方法需要在.h文件中聲明。
3.重寫系統(tǒng)alloc方法并拋異常
疑問:為什么return返回的是[super alloc]
解答:調(diào)用系統(tǒng)默認(rèn)的方法,因?yàn)槲覀儾恢婪峙鋬?nèi)存的實(shí)現(xiàn),又不想要覆蓋原來方法的實(shí)現(xiàn),所以就需要調(diào)用super alloc方法并將其返回
4.演示結(jié)果,外界調(diào)用alloc崩潰
UIApplication的常用屬性
- 設(shè)置應(yīng)用程序圖標(biāo)右上角的紅色提醒數(shù)字
@property(nonatomic) NSInteger applicationIconBadgeNumber;
- 設(shè)置聯(lián)網(wǎng)指示器的可見性
@property(nonatomic,getter=isNetworkActivityIndicatorVisible) BOOL NetworkActivityIndicatorVisible;
聯(lián)網(wǎng)指示器 - iOS 7 的狀態(tài)欄
- 打電話,發(fā)短信(需要真機(jī))打開網(wǎng)頁
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIApplication *application = [UIApplication sharedApplication];
//1.獲取應(yīng)用程序圖標(biāo)的提醒數(shù)字
/**
設(shè)置后無效,查看屬性下的英文注釋:
set to 0 to hide. default is 0. In iOS 8.0 and later, your application must register for user notifications using -[UIApplication registerUserNotificationSettings:] before
*/
application.applicationIconBadgeNumber = 10;
//創(chuàng)建通知對(duì)象
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
//注冊(cè)用戶通知
[application registerUserNotificationSettings:setting];
//2.設(shè)置聯(lián)網(wǎng)提示
application.networkActivityIndicatorVisible = YES;
//3.設(shè)置狀態(tài)欄
//application.statusBarHidden = YES;
/**
設(shè)置無效,查看官方注釋
Setting statusBarHidden does nothing if your application is using the default UIViewController-based status bar system.
iOS7之后默認(rèn)交給控制器管理狀態(tài)欄
*/
// - (BOOL)prefersStatusBarHidden NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to NO
// Override to return the type of animation that should be used for status bar changes for this view controller. This currently only affects changes to prefersStatusBarHidden.
//配置info:添加key:View controller-based status bar appearance,并設(shè)置為NO,將狀態(tài)欄的設(shè)置交給application來管理
//方法已經(jīng)過期
[application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
//4.打電話 發(fā)信息 打開網(wǎng)頁
//打開網(wǎng)頁:URL:資源的唯一標(biāo)示;協(xié)議頭+資源路徑
//原理:根據(jù)協(xié)議頭判斷用什么軟件打開
[application openURL:[NSURL URLWithString:@"http://www.baidu.com"]];
}
UIApplication和delegate
- 所有的移動(dòng)操作系統(tǒng)都有個(gè)致命的缺點(diǎn):app很容易受到打擾。比如一個(gè)來電或者是鎖屏?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來處理系統(tǒng)事件
delegate可處理的事件包括:
- 應(yīng)用程序的生命周期事件(如程序的啟動(dòng)和關(guān)閉)
- 系統(tǒng)事件(如來電)
- 內(nèi)存警告
delegate方法講解:
//應(yīng)用程序啟動(dòng)完成后就會(huì)調(diào)用AppDelegate方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
return YES;
}
//當(dāng)應(yīng)用程序失去焦點(diǎn)的時(shí)候調(diào)用,只有當(dāng)應(yīng)用程序完全獲取焦點(diǎn)的時(shí)候才能夠與用戶交互,所謂的獲取焦點(diǎn)我的理解為app啟動(dòng)布滿屏幕。
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
//當(dāng)應(yīng)用程序進(jìn)入后臺(tái)時(shí)候調(diào)用
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
//當(dāng)應(yīng)用程序即將進(jìn)入前臺(tái)的時(shí)候調(diào)用
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
//當(dāng)應(yīng)用程序獲得焦點(diǎn)的時(shí)候調(diào)用
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
//當(dāng)應(yīng)用程序關(guān)閉的時(shí)候調(diào)用
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end
各方法的調(diào)用時(shí)機(jī)的演示以及講解
1.程序一啟動(dòng)未做任何操作
程序加載完畢,并獲得焦點(diǎn)
2.點(diǎn)擊home鍵進(jìn)入手機(jī)主界面
application先失去焦點(diǎn)然后 進(jìn)入后臺(tái)
3.點(diǎn)擊應(yīng)用重新進(jìn)入
application進(jìn)入前臺(tái)然后獲得焦點(diǎn)
4.雙擊home鍵關(guān)閉程序
程序關(guān)閉
由控制臺(tái)打印結(jié)果可知按照上面的操作,先后順序?yàn)椋?br> 程序加載完畢-->程序獲得焦點(diǎn)-->程序失去焦點(diǎn)-->程序進(jìn)入后臺(tái)-->程序進(jìn)入前臺(tái)-->程序獲得焦點(diǎn)-->程序關(guān)閉
程序的啟動(dòng)流程
查看官方文檔,了解參數(shù)的介紹
第三個(gè)參數(shù):UIApplication類名或者子類的名稱,如果傳nil的話默認(rèn)為@“UIApplication”
第四個(gè)參數(shù):UIApplication的代理的類型名稱,蘋果使用NSStringFromClass([AppDelegate class])方法,獲得對(duì)應(yīng)類名,使用該方法除了可以避免輸入錯(cuò)誤的同時(shí)還具有提示功能。
UIApplication底層實(shí)現(xiàn)原理:
1.根據(jù)principalClassName(第三個(gè)參數(shù))傳遞的類名創(chuàng)建一個(gè)UIApplication對(duì)象
2.創(chuàng)建UIApplication代理對(duì)象,給UIApplication對(duì)象設(shè)置代理
3.開啟主運(yùn)行事件循環(huán),處理事件,保持程序一直運(yùn)行(后期runloop講解)
4.加載Info.plist,判斷application的Info.pist文件是否指定main,如果指定main就會(huì)記載nib文件