一、UIApplication
1. 簡介:
- UIApplication對象代表的就是iOS系統(tǒng)中的一個應(yīng)用程序
- 每一個應(yīng)用都有自己的UIApplication對象耐朴,而且是單例的
- 通過[UIApplication sharedApplication]可以獲得這個單例對象(通過打印兩個Application對象驗證)
- 一個iOS程序啟動后創(chuàng)建的第一個對象就是UIApplication對象
- 利用UIApplication對象漏麦,能進(jìn)行一些應(yīng)用級別的操作
2.常用屬性和方法:
// 應(yīng)用程序代理
@property(nullable, nonatomic,assign) id<UIApplicationDelegate> delegate;
// 應(yīng)用程序的主窗口
@property(nullable, nonatomic,readonly) UIWindow *keyWindow;
// 應(yīng)用程序的窗口集合
@property(nonatomic,readonly) NSArray<__kindof UIWindow *> *windows;
// 設(shè)置網(wǎng)絡(luò)狀態(tài)默認(rèn)為NO,YES可以在系統(tǒng)狀態(tài)欄顯示一個轉(zhuǎn)動的菊花
@property(nonatomic,getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible __TVOS_PROHIBITED;
// 設(shè)置屏幕是否為常亮默認(rèn)為NO,YES為常亮
@property(nonatomic,getter=isIdleTimerDisabled) BOOL idleTimerDisabled;
// 用來顯示或者隱藏系統(tǒng)狀態(tài)欄默認(rèn)為NO,設(shè)置YES為隱藏系統(tǒng)狀態(tài)欄
@property(readonly, nonatomic,getter=isStatusBarHidden) BOOL statusBarHidden __TVOS_PROHIBITED;
// 設(shè)置系統(tǒng)狀態(tài)欄的樣式默認(rèn)為UIStatusBarStyleDefault
/*UIStatusBarStyle常用枚舉值
UIStatusBarStyleDefault //黑暗模式
UIStatusBarStyleLightContent //燈光模式
*/
@property(readonly, nonatomic) UIStatusBarStyle statusBarStyle __TVOS_PROHIBITED;
// 可以設(shè)置應(yīng)用程序圖標(biāo)上面的數(shù)字
@property(nonatomic) NSInteger applicationIconBadgeNumber __TVOS_PROHIBITED;
// 在iOS8.0以后 要使用UIApplication給應(yīng)用程序設(shè)置圖標(biāo)數(shù)字時亮钦,要注冊一個系統(tǒng)通知UIUserNotificationTypeBadge 就可以設(shè)置應(yīng)用程序圖標(biāo)上面的數(shù)字
/* 代碼示例:
if ([[[UIDevice currentDevice] systemVersion] floatValue] > 8.0) {
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:setting];
}
[UIApplication sharedApplication].applicationIconBadgeNumber = 10;
*/
// 類方法,用來獲取UIApplication對象
+ (UIApplication *)sharedApplication NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead.");
// 可以打開一個指定的NSURL所指的資源
- (BOOL)openURL:(NSURL*)url NS_EXTENSION_UNAVAILABLE_IOS("");
3. 狀態(tài)欄的管理
- 從iOS7開始忿族,系統(tǒng)提供了2種管理狀態(tài)欄的方式
- 通過UIViewController管理(每一個UIViewController都可以擁有自己不同的狀態(tài)欄)
- 通過UIApplication管理(一個應(yīng)用程序的狀態(tài)欄都由它統(tǒng)一管理)
-
在iOS7之后啥么,默認(rèn)情況下往枷,狀態(tài)欄都是由UIViewController管理的框产,若想通過UIApplication進(jìn)行管理,則需要配置plist文件
// 示范代碼:
// 隱藏系統(tǒng)狀態(tài)欄
[UIApplication sharedApplication].statusBarHidden = YES;
// 設(shè)置系統(tǒng)狀態(tài)欄樣式
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
// 隱藏系統(tǒng)狀態(tài)欄帶動畫
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
// 設(shè)置系統(tǒng)狀態(tài)欄樣式帶動畫
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
4. openURL方法的應(yīng)用
/*
NSURL統(tǒng)一資源定位符 格式 > 協(xié)議://路徑
*/
// 創(chuàng)建UIApplication對象
UIApplication *app = [UIApplication sharedApplication];
// 打電話 tel為打電話協(xié)議
[app openURL:[NSURL URLWithString:@"tel://10086"]];
// 發(fā)短信 sms為發(fā)短信協(xié)議
[app openURL:[NSURL URLWithString:@"sms://10086"]];
// 打開網(wǎng)址 http為上網(wǎng)協(xié)議
[app openURL:[NSURL URLWithString:@"http://www.ithemima.com"]];
// 發(fā)送郵件 mailto為發(fā)送郵件協(xié)議
[app openURL:[NSURL URLWithString:@"mailto://zhangsan@itcast.cn"]];
二错洁、應(yīng)用程序的狀態(tài)介紹
- Not running (未運(yùn)行狀態(tài)):應(yīng)用程序未啟動或應(yīng)用程序被系統(tǒng)終止秉宿。
- Inactive(不活動狀態(tài)):程序在前臺運(yùn)行,但不能接收事件屯碴。當(dāng)應(yīng)用要從一個狀態(tài)切換到另一個不同的狀態(tài)時描睦,中途過渡會短暫停留在此狀態(tài)。
- Active(活動):程序在前臺運(yùn)行且能接受事件导而。這是應(yīng)用在前臺運(yùn)行時所處的正常狀態(tài)忱叭。
- Background(后臺):應(yīng)用處在后臺運(yùn)行,并且還在執(zhí)行代碼今艺。大多數(shù)將要進(jìn)入Suspended狀態(tài)的應(yīng)用韵丑,會先短暫進(jìn)入此狀態(tài)。如果應(yīng)用請求更多額外的執(zhí)行時間虚缎,該應(yīng)用會在此狀態(tài)保持更長一段時間撵彻。另外,如果一個應(yīng)用要求啟動時直接進(jìn)入后臺運(yùn)行实牡,這樣的應(yīng)用會直接從Not running狀態(tài)進(jìn)入Background狀態(tài)陌僵,中途不會經(jīng)過Inactive狀態(tài)。比如创坞,沒有界面的應(yīng)用碗短,總之,如果應(yīng)用直接進(jìn)入Background狀態(tài)题涨,該應(yīng)用界面不會被顯示出來偎谁。
- Suspended(掛起):應(yīng)用處在后臺奔坟,并且沒有執(zhí)行任何代碼。系統(tǒng)會自動將應(yīng)用轉(zhuǎn)入該狀態(tài)搭盾,應(yīng)用依然駐留內(nèi)存,但不執(zhí)行任何程序代碼婉支。當(dāng)系統(tǒng)發(fā)生低內(nèi)存警告時鸯隅,系統(tǒng)會將處于Suspend狀態(tài)的應(yīng)用徹底移除內(nèi)存,從而為前臺應(yīng)用釋放更多的內(nèi)存向挖。
三蝌以、UIApplicationDelegate
1.簡介:
UIApplicationDelegate定義的方法主要工作之一就是跟蹤應(yīng)用程序的狀態(tài)變化,當(dāng)應(yīng)用程序發(fā)生重大的運(yùn)行時事件時如:應(yīng)用啟動完畢何之、低內(nèi)存警告和應(yīng)用程序終止,進(jìn)入前臺跟畅、后臺、可見等的時候會在適當(dāng)?shù)臅r機(jī)通知代理做出響應(yīng)
2.代理方法及對應(yīng)的執(zhí)行時機(jī)
// 應(yīng)用程序啟動完畢
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(@"應(yīng)用程序啟動完畢");
return YES;
}
// 應(yīng)用程序變?yōu)椴换钴S狀態(tài)
- (void)applicationWillResignActive:(UIApplication *)application {
NSLog(@"應(yīng)用程序變?yōu)椴换钴S狀態(tài)");
}
// 應(yīng)用程序進(jìn)入后臺
- (void)applicationDidEnterBackground:(UIApplication *)application {
/**
1.停止timers并終止其他周期性的任務(wù)溶推。
2.停止任何正在運(yùn)行的元數(shù)據(jù)查詢徊件。
3.不要初始化任何新的任務(wù)。
4.暫停電影播放(在AirPlay上播放的除外)蒜危。
5.游戲進(jìn)入暫停狀態(tài)虱痕。
6.暫停所有執(zhí)行非關(guān)鍵代碼的調(diào)度隊列和操作隊列(即使處于Inactive狀態(tài),依然可以繼續(xù)處理網(wǎng)絡(luò)請求和其他耗時的后臺任務(wù))辐赞。
*/
NSLog(@"應(yīng)用程序進(jìn)入后臺");
}
// 應(yīng)用程序進(jìn)入前臺
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(@"應(yīng)用程序進(jìn)入前臺");
}
// 應(yīng)用程序變?yōu)榛钴S狀態(tài)
- (void)applicationDidBecomeActive:(UIApplication *)application {
// 恢復(fù)在- (void)applicationWillResignActive:(UIApplication *)application方法中做的所有任務(wù)
// 但游戲的恢復(fù)應(yīng)該讓用戶自己決定部翘。
NSLog(@"應(yīng)用程序變?yōu)榛钴S狀態(tài)");
}
// 應(yīng)用程序即將終止
- (void)applicationWillTerminate:(UIApplication *)application {
NSLog(@"應(yīng)用程序即將終止");
}
// 應(yīng)用程序收到內(nèi)存警告
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application{
NSLog(@"應(yīng)用程序收到內(nèi)存警告");
}
四、UIApplicationMain
- UIApplicationMain是程序主函數(shù)中執(zhí)行的一個函數(shù)
int UIApplicationMain ( int argc, char * _Nonnull argv[], NSString *principalClassName, NSString *delegateClassName );
/*
1.返回值為一個int類型
2.第一個參數(shù):對應(yīng)main函數(shù)的第一個參數(shù):參數(shù)個數(shù)
3.第二個參數(shù):對應(yīng)main函數(shù)的第二個參數(shù):參數(shù)列表
4.第三個參數(shù):principalClassName UIApplication類或子類的類名字,如果為nil.默認(rèn)為UIApplication
5.第四個參數(shù):delegateClassName 應(yīng)用程序代理類的名字
*/
- UIApplicationMain函數(shù)會根據(jù)principalClassName創(chuàng)建 UIApplication對象响委,根據(jù)delegateClassName創(chuàng)建一個delegate對象新思,并將該delegate對象賦值給UIApplication對象中的delegate屬性
- 接著會建立應(yīng)用程序的Main Runloop(事件循環(huán)),進(jìn)行事件的處理(首先會在程序完畢后調(diào)用delegate對象的application:didFinishLaunchingWithOptions:方法)
- 程序正常退出時UIApplicationMain函數(shù)才返回
五赘风、應(yīng)用程序的啟動
程序啟動的完整過程:
- 先執(zhí)行main函數(shù)夹囚,main內(nèi)部會調(diào)用UIApplicationMain函數(shù),該函數(shù)的聲明如下:
int UIApplicationMain(int argc, char argv[], NSString principalClassName, NSString *delegateClassName)。
//argc邀窃、argv:標(biāo)準(zhǔn)main函數(shù)的參數(shù)崔兴,直接傳遞給UIApplicationMain進(jìn)行相關(guān)處理即可
//principalClassName:指定應(yīng)用程序類,該類必須是UIApplication(或子類)蛔翅。如果為nil,則用UIApplication類作為默認(rèn)值
//delegateClassName:指定應(yīng)用程序類的代理類敲茄,該類必須遵守UIApplicationDelegate協(xié)議。
- 在UIApplicationMain函數(shù)里面做了如下幾件事情:
(1). 根據(jù)傳入的第三個參數(shù)創(chuàng)建UIApplication對象或它的子類對象山析。如果該參數(shù)為nil,直接使用該UIApplication來創(chuàng)建堰燎。(該參數(shù)只能傳人UIApplication或者是它的子類)
(2). 根據(jù)傳入的第四個參數(shù)創(chuàng)建AppDelegate對象,并將該對象賦值給第1步創(chuàng)建的 UIApplication對象的delegate屬性。
(3). 開啟一個事件循環(huán),循環(huán)監(jiān)控應(yīng)用程序發(fā)生的事件笋轨。每監(jiān)聽到對應(yīng)的系統(tǒng)事件時秆剪,就會通知AppDelegate赊淑。
3、接著加載控制器view分兩種情況
有storyboard
1.應(yīng)用程創(chuàng)建一個UIWindow對象(繼承自UIView),并設(shè)置為AppDelegate的window屬性仅讽。
2.加載Info.plist文件陶缺,讀取最主要storyboard文件的名稱。
3.加載最主要的storyboard文件洁灵,創(chuàng)建白色箭頭所指的控制器對象饱岸。并且設(shè)置控制器為UIWindow的rootViewController屬性(根控制器)。
4.展示UIWindow,展示之前會將添加rootViewController的view到UIWindow上面(在這一步才會創(chuàng)建控制器的view),其內(nèi)部會執(zhí)行該行代碼:[window addSubview: window.rootViewController.view];
-
沒有storyboard
- 1.首先會調(diào)用delegate對象的application:didFinishLaunchingWithOptions:方法徽千。
- 2.在application:didFinishLaunchingWithOptions:方法中需要主動創(chuàng)建 UIWindow對象苫费。并設(shè)置為AppDelegate的window屬性。
- 3.主動創(chuàng)建一個 UIViewController對象双抽,并賦值給window的rootViewController屬性百框。
- 調(diào)用 window的makeKeyAndVisible方法顯示窗口。
注:如果重寫了loadView方法,則會通過UIViewController中的loadView方法中的代碼創(chuàng)建view牍汹,而不會加載storyboard
4铐维、顯示控制的view到手機(jī)屏幕