一.UIApplication 簡介
(1)UIApplication對象是應用程序的象徵,一個UIApplication對象就表明一個應用程序。
(2)每個Application都有本身的UIApplication對象,並且是單例的,若是用試圖再去實例化一個UIApplication則會報錯:
[ [ UIApplication alloc ] init ];。
(3)經過[UIApplication sharedApplication]能夠得到這個單例對象。
(4) 一個iOS程序啓動後建立的第一個對象就是UIApplication對象,且只有一個(可經過代碼獲取兩個UIApplication對象,打印地址相同)。
(5)利用UIApplication對象,能進行一些應用級別的操做。
二.應用級別的操做舉例
1)設置應用程序圖標右上角的紅色提醒數字(如QQ消息的時候,圖標上面會顯示1,2,3條新信息等。)
@property
(
nonatomic
)
NSInteger
applicationIconBadgeNumber
__TVOS_PROHIBITED
;
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
//點擊屏幕會調用該方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UIApplication *app = [UIApplication sharedApplication];
//註冊通知
UIUserNotificationSettings *nitice = [UIUserNotificationSettings
settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[app registerUserNotificationSettings:nitice];
//IconBadgeNumber
app.applicationIconBadgeNumber = 20;
}
@end
運行效果:
2)設置聯網指示器的可見性
@property
(
nonatomic
,
getter
=isNetworkActivityIndicatorVisible)
BOOL
networkActivityIndicatorVisible
__TVOS_PROHIBITED
;
代碼:
app.
networkActivityIndicatorVisible
=
YES
;
運行效果:
3)管理狀態欄
從iOS7開始,系統提供了2種管理狀態欄的方式
a.經過UIViewController管理(每個UIViewController均可以擁有本身不一樣的狀態欄).
在iOS7中,默認狀況下,狀態欄都是由UIViewController管理的,UIViewController實現下列方法就能夠輕鬆管理狀態欄的可見性和樣式
狀態欄的樣式 - (UIStatusBarStyle)preferredStatusBarStyle;
狀態欄的可見性 -(BOOL)prefersStatusBarHidden;
代碼:
#pragma mark - 狀態欄的樣式
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}
#pragma mark - 是否隱藏狀態欄(no)
- (BOOL)prefersStatusBarHidden {
return NO;
}
b.經過UIApplication管理(一個應用程序的狀態欄都由它統一管理)
若是想利用UIApplication來管理狀態欄,首先得修改Info.plist的設置
代碼:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
//獲取
UIApplication *app = [UIApplication sharedApplication];
//註冊通知
UIUserNotificationSettings *nitice =
[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[app registerUserNotificationSettings:nitice];
//IconBadgeNumber
app.applicationIconBadgeNumber = 20;
app.networkActivityIndicatorVisible = YES;
//設置狀態欄
app.statusBarHidden = NO;
app.statusBarStyle = UIStatusBarStyleDefault;
}
注意:既然兩種均可以對狀態欄進行管理,那麼何時該用什麼呢?
若是狀態欄的樣式只設置一次,那就用UIApplication來進行管理;
若是狀態欄是否隱藏,樣式不同那就用控制器進行管理。
4)openURL:方法
UIApplication有個功能十分強大的openURL:方法
- (
BOOL
)openURL:(
NSURL
*)url
openURL:方法的部分功能有
打電話
[app openURL:[NSURLURLWithString:@"tel://10010"]];
發短信
[app openURL:[NSURLURLWithString:@"sms://10010"]];
發郵件
[app openURL:[NSURLURLWithString:@"mailto://xxxxxx@qq.com"]];
打開一個網頁資源
打開其餘app程序 openURL方法,能夠打開其餘APP。網絡
URL:
URL:統一資源定位符,用來惟一的表示一個資源。
URL格式: 協議頭://主機地址/資源路徑
本地資源:file:///users/apple/desktop/abc.png(主機地址省略)
三. UIApplication Delegate
爲何會UIApplication Delegate?
移動操做系統都有個致命的缺點:app容易受到打擾。好比電話或者鎖屏會致使app進入後臺甚至被終止。此時app會產生一些系統事件,UIApplication會通知它的delegate對象,讓delegate代理來處理這些系統事件。
總結:
AppDelegate
的主要做用就是處理
(
監聽
)
應用程序自己的各類事件。
應用程序啓動完畢
應用程序進入後臺
應用程序進入前臺
等,應用程序自身的一些事件
要想成爲
UIApplication
的代理對象
,
必須遵照
:UIApplicationDelegate
協議。每次建立新項目,Xcode會幫我生成一個「AppDelegate」的類,它就是代理,而且該類已經默認遵循了UIApplicationDelegate的代理,且成爲了代理(在程序啓動部分會有更多解釋)。
UIApplication的代理協議有許多,AppDelegate這個類默認遵循了
<
UIApplicationDelegate
> ,並且實現了部分代理方法,從而監控咱們的應用程序。
UIApplication的代理屬性:
@property
(
nullable
,
nonatomic
,
assign
)
id
<
UIApplicationDelegate
> delegate;
實現的代理方法在
AppDelegate.m中
以下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 當應用程序啓動完畢的時候就會調用(系統自動調用)
NSLog(@"%s",__func__);
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// 即將失去活動狀態的時候調用
NSLog(@"%s",__func__);
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// 應用程序進入後臺的時候調用
NSLog(@"%s",__func__);
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
/ / 應用程序即將進入前臺的時候調用
NSLog(@"%s",__func__);
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// 從新激活(可以和用戶交互)
NSLog(@"%s",__func__);
}
- (void)applicationWillTerminate:(UIApplication *)application {
// 應用程序即將被銷燬的時候會調用該方法
NSLog(@"%s",__func__);
}
應用程序通常有五個狀態:官方文檔app.states
4、程序啓動原理
1.先簡單回顧一下,咱們最經典的應用程序hello world:
它告訴咱們,應用程序的入口是main函數;
#include<stdio.h>
int main(int argc,char* argv[])
{
printf("hello, world\n");
return 0;
}
2.再看一段Linux下的qt的一個應用程序:
它的程序入口也是main函數,且
app.exec();將應用程序的控制權傳遞給
Qt
,進入事件循環的狀態,等待用戶操做。
#include <QtGui>
int main(int argc,char *argv[]) {
QApplication app(argc,argv);
QLabel label(QString("hellow qt"));
label.show();
app.exec();
}
3.
由此,能夠猜想iOS的程序的入口也是main函數,最終程序也會進入一個事件的循環,等待用戶操做,監控;
在iOS的main.m,找到了程序的入口main函數,該函數只有一句;
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
即:main函數中調用了
UIApplicationMain方法
int
UIApplicationMain(
int
argc,
char
*argv[],
NSString
*
__nullable
principalClassName,
NSString
*
__nullable
delegateClassName);
- argc:argc是命令行總的參數個數
- argv:argv[]是argh個參數,記錄用戶輸入的參數;
- principalClassName:指定應用程序類名(app的象徵),該類必須是UIApplication(或子類),若是爲nil,則用UIApplication類做爲默認值
- delegateClassName:指定應用程序的代理類,UIApplicationDelegate協議中定義的方法,在該類中實現;
UIApplicationMain函數會根據principalClassName建立UIApplication對象,根據delegateClassName建立一個delegate對象,並將該delegate對象賦值給UIApplication對象中的delegate屬性,接着會創建應用程序的Main Runloop(事件循環),進行事件的處理(首先會在程序完畢後調用delegate對象的application:didFinishLaunchingWithOptions:方法程序正常退出時UIApplicationMain函數才返回。
總結:UIApplicationMain就是讓咱們的應用程序和代理之間創建聯繫,而後進入Runloop,進行事件處理;咱們直接給UIApplicationMain傳遞應用程序的類名和代理的類名也是同樣的。
即:
return
UIApplicationMain
(argc, argv,
@"UIApplication"
,
@"AppDelegate"
);
4.程序啓動的完整過程:
1.main函數
UIApplicationMain
* 建立UIApplication對象
* 建立UIApplication的delegate對象
2.delegate對象開始處理(監聽)系統事件
2.1沒有storyboard
* 程序啓動完畢的時候, 就會調用代理的application:didFinishLaunchingWithOptions:方法
* 在application:didFinishLaunchingWithOptions:中建立UIWindow
* 建立和設置UIWindow的rootViewController
* 顯示窗口
代碼:
#import "AppDelegate.h"
#import "ViewController.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
ViewController *vc = [[ViewController alloc] init];
self.window.rootViewController = vc;
vc.view.backgroundColor = [UIColor redColor];
[self.window makeKeyAndVisible];
return YES;
}
2.2.
(有storyboard)
根據Info.plist得到最主要storyboard的文件名,加載最主要的storyboard
* 建立UIWindow
* 建立和設置UIWindow的rootViewController
* 顯示窗口