UIApplication簡(jiǎn)單介紹
UIApplication對(duì)象是應(yīng)用程序的象征,一個(gè)UIApplication對(duì)象就代表一個(gè)應(yīng)用程序报账。
每一個(gè)應(yīng)用都有自己的UIApplication對(duì)象许赃,而且是單例的概耻,如果試圖在程序中新建一個(gè)UIApplication對(duì)象猫缭,那么將報(bào)錯(cuò)提示麻养。
通過
[UIApplication sharedApplication]
可以獲得這個(gè)單例對(duì)象一個(gè)iOS程序啟動(dòng)后創(chuàng)建的第一個(gè)對(duì)象就是UIApplication對(duì)象越庇,且只有一個(gè)(通過代碼獲取兩個(gè)UIApplication對(duì)象罩锐,打印地址可以看出地址是相同的)。
利用UIApplication對(duì)象卤唉,能進(jìn)行一些應(yīng)用級(jí)別的操作,比如 打電話 發(fā)短信 打開網(wǎng)頁(yè)等等,這個(gè)我們下面會(huì)具體討論.
UIApplication單例實(shí)現(xiàn)
當(dāng)我們?cè)诔绦蛑?調(diào)用[[UIApplication alloc] init];
來獲取UIApplication對(duì)象的時(shí)候,程序崩潰,并且給我們?nèi)缦绿崾?
UIApplication[27299:5432002] *** Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 'There can only be one UIApplication instance.'
下面我們通過一個(gè)Person類來模仿一下系統(tǒng)單例的實(shí)現(xiàn)
#import "Person.h"
@implementation Person
//靜態(tài)變量
static Person *_instance = nil;
+(void)load{
_instance = [[Person alloc] init];
}
+(instancetype)allocWithZone:(struct _NSZone *)zone{
if (_instance) {
NSException *exception = [NSException exceptionWithName:@"NSInternalInconsistencyException" reason:@"There can only be one Person instance." userInfo:nil];
[exception raise];
}
return [super allocWithZone:zone];
}
+ (instancetype) sharedInstance{
return _instance;
}
@end
首先我們來看看他們的內(nèi)存地址:
Person *p1 = [Person sharedInstance];
Person *p2 = [Person sharedInstance];
NSLog(@"%p %p",p1,p2);
打印結(jié)果:
UIApplication[27436:5450616] 0x60000001ae50 0x60000001ae50
內(nèi)存地址是一樣的,說明這是同一個(gè)對(duì)象
當(dāng)我們通過 [[Person alloc] init];
來創(chuàng)建Person對(duì)象的時(shí)候 程序崩潰,并且給我們?nèi)缦绿崾?
UIApplication[27464:5453213] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'There can only be one Person instance.'
應(yīng)用程序啟動(dòng)原理
我們首先來看看 main.m
入口函數(shù)
int main(int argc, char * argv[]) {
@autoreleasepool {
//參數(shù)三:該參數(shù)為UIApplication類名或者其子類名稱涩惑,nil 相當(dāng)于 @"UIApplicaiton";
//參數(shù)四:該參數(shù)為UIApplicaiton的代理名稱 NSStringFromClass([AppDelegate class] 相當(dāng)于 AppDelegate
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
此時(shí)我們可以根據(jù)UIApplicationMain函數(shù)了解程序啟動(dòng)的大體過程
- 根據(jù)傳遞的類名創(chuàng)建UIApplication對(duì)象,同時(shí)創(chuàng)建UIApplication代理對(duì)象桑驱,并給UIApplicaiton對(duì)象設(shè)置代理
- 開啟主運(yùn)行循環(huán)處理事件竭恬,保持程序一直運(yùn)行
- 加載
info.plist
,判斷是否指定 mian 如果指定就去加載,否則程序啟動(dòng)完畢的時(shí)候, 就會(huì)調(diào)用代理的application:didFinishLaunchingWithOptions:
方法. 在該方法中創(chuàng)建UIWindow
對(duì)象,顯示窗口
iOS應(yīng)用程序啟動(dòng)過程:
image
利用UIApplication對(duì)象進(jìn)行一些應(yīng)用級(jí)別的操作
1. 設(shè)置應(yīng)用程序圖標(biāo)Badge
@property(nonatomic) NSInteger applicationIconBadgeNumber;
UIApplication *app = [UIApplication sharedApplication];
app.applicationIconBadgeNumber = 5;
2. 設(shè)置聯(lián)網(wǎng)指示器的可見性
@property(nonatomic,getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible __TVOS_PROHIBITED; // showing network spinning gear in status bar. default is NO
application.networkActivityIndicatorVisible= YES;
3. 管理狀態(tài)欄
從iOS7開始,系統(tǒng)提供了2種管理狀態(tài)欄的方式
- 通過UIViewController管理(每一個(gè)UIViewController都可以擁有自己不同的狀態(tài)欄)在iOS7中熬的,默認(rèn)情況下痊硕,狀態(tài)欄都是由UIViewController管理的,UIViewController實(shí)現(xiàn)下列方法就可以輕松管理狀態(tài)欄的可見性和樣式
#pragma mark-設(shè)置狀態(tài)欄的樣式
-(UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleDefault;
}
#pragma mark-設(shè)置狀態(tài)欄是否隱藏(否)
-(BOOL)prefersStatusBarHidden
{
return NO;
}
-
通過UIApplication管理(一個(gè)應(yīng)用程序的狀態(tài)欄都由它統(tǒng)一管理)如果想利用UIApplication來管理狀態(tài)欄押框,首先得修改Info.plist的設(shè)置岔绸,添加選中行,并設(shè)置為NO即可
image
UIApplication *app=[UIApplication sharedApplication];
app.statusBarHidden = NO;
app.statusBarStyle = UIStatusBarStyleDefault;
總結(jié):
如果狀態(tài)欄的樣式只設(shè)置一次橡伞,那就用UIApplication來進(jìn)行管理盒揉,并且UIApplication可以提供動(dòng)畫效果;
如果狀態(tài)欄是否隱藏兑徘,樣式不一那就用每個(gè)控制器對(duì)自己的狀態(tài)欄進(jìn)行管理刚盈。
4. 判斷程序運(yùn)行狀態(tài)
系統(tǒng)為我們提供如下幾種運(yùn)行狀態(tài):
typedef NS_ENUM(NSInteger, UIApplicationState) {
UIApplicationStateActive,
UIApplicationStateInactive,
UIApplicationStateBackground
} NS_ENUM_AVAILABLE_IOS(4_0);
判斷:
UIApplication *app = [UIApplication sharedApplication];
if(app.applicationState ==UIApplicationStateActive){
NSLog(@"運(yùn)行狀態(tài)");
}
if(app.applicationState ==UIApplicationStateBackground){
NSLog(@"在后臺(tái)");
}