簡析UIApplication及UIApplicationdelegate

  • UIApplication對象是應用程序的象徵

  • 每一個應用都有自己的UIApplication對象,而且是單例的

  • 通過[UIApplication sharedApplication]可以獲得這個單例對象

  • 一個iOS程序啓動後創建的第一個對象就是UIApplication對象

  • 利用UIApplication對象,能進行一些應用級別的操作

UIApplication的常見屬性

1.設置應用提醒數字
2.可以設置聯網狀態,
3.可以設置狀態欄,
4.可以打電話,發短信,打開網頁。

    // UIApplication在程序啓動的時候,由系統幫我們創建
    UIApplication *app =  [UIApplication sharedApplication];

    // 1.設置提醒數字,可以設置聯網狀態,可以設置狀態欄,可以打電話,發短信,打開網頁。

    // iOS8之後,apple 爲了保護用戶隱私 將提醒事件默認需要進行用戶許可 -[UIApplication registerUserNotificationSettings:]
    // 設置提醒數字
    app.applicationIconBadgeNumber = 10;

    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];

    // 註冊一個用戶的通知
    [app registerUserNotificationSettings:settings];

    // 設置聯網狀態
    [app setNetworkActivityIndicatorVisible:YES];

iOS7之後的狀態欄

  • 從iOS7開始,系統提供了2種管理狀態欄的方式

    • 通過UIViewController管理(每一個UIViewController都可以擁有自己不同的狀態欄)
    • 通過UIApplication管理(一個應用程序的狀態欄都由它統一管理)
  • 在iOS7之後,默認情況下,狀態欄都是由UIViewController管理的,UIViewController實現下列方法就可以輕鬆管理狀態欄的可見性和樣式

    • 狀態欄的樣式
      -(UIStatusBarStyle)preferredStatusBarStyle;
    • 狀態欄的可見性
      -(BOOL)prefersStatusBarHidden;
      如果想利用UIApplication來管理狀態欄,首先得修改Info.plist的設置


Snip20150707_1.png
  // 設置狀態欄
    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];

     UIApplication *app =  [UIApplication sharedApplication];
    // 打開網頁
    // URL:資源路徑
    // URL組成: 協議頭/路徑 http:// file:// tel://
    //  根據url的協議頭判斷用什麼軟件
    // http://www.baidu.com
    [app openURL:[NSURL URLWithString:@"http://www.baidu.com"]];

分析 :既然兩種都可以對狀態欄進行管理,那麼什麼時候該用什麼呢?

  • 如果狀態欄的樣式只設置一次,那就用UIApplication來進行管理;
  • 如果狀態欄是否隱藏,樣式不一樣那就用控制器進行管理。
    UIApplication來進行管理有額外的好處,可以提供動畫效果。

UIApplication Delegate

  • 所有的移動操作系統都有個致命的缺點:app很容易受到打擾。比如一個來電或者鎖屏會導致app進入後臺甚至被終止
    [if ppt]•[endif]
  • 還有很多其它類似的情況會導致app受到干擾,在app受到干擾時,會產生一些系統事件,這時UIApplication會通知它的delegate對象,讓delegate代理來處理這些系統事件

  • delegate可處理的事件包括:

    • 應用程序的生命週期事件(如程序啓動和關閉)
    • 系統事件(如來電)
    • 內存警告
    • ...


Snip20150707_2.png
  • AppDelegate的相關方法
#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

#warning AppDelegate沒有自己創建,系統會默認幫我們創建。

// 處理應用程序的一些生命週期方法
// 內存警告

// 程序啓動完成的時候調用
// __func__:表示當前的方法在哪個類裏面調用
// -[AppDelegate application:didFinishLaunchingWithOptions:]
- (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 {

}

// 當應用程序獲取焦點的時候調用
// 當用戶完全獲取焦點的時候,才能跟界面交互
- (void)applicationDidBecomeActive:(UIApplication *)application {
}

// 當應用程序關閉的時候調用
- (void)applicationWillTerminate:(UIApplication *)application {
}

// 當程序接收到內存警告的時候調用
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
    // 清空圖片緩存
    NSLog(@"%s",__func__);
}

@end

程序啓動原理


Snip20150707_3.png

UIApplicationMain

main函數中執行了一個UIApplicationMain這個函數

int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);
  • argc、argv:直接傳遞給UIApplicationMain進行相關處理即可 
  • principalClassName:指定應用程序類名(app的象徵),該類必須是UIApplication(或子類)。如果爲nil,則用UIApplication類作爲默認值
  • delegateClassName:指定應用程序的代理類,該類必須遵守UIApplicationDelegate協議
  • UIApplicationMain函數會根據principalClassName創建UIApplication對象,根據delegateClassName創建一個delegate對象,並將該delegate對象賦值給UIApplication對象中的delegate屬性
    接着會建立應用程序的Main Runloop(事件循環),進行事件的處理(首先會在程序完畢後調用delegate對象的application:didFinishLaunchingWithOptions:方法)
  • 程序正常退出時UIApplicationMain函數才返回
#import <UIKit/UIKit.h>
#import "AppDelegate.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        // nil -> @"UIApplication"
        // principalClassName:只能傳入UIApplication或者他的子類
        // delegateClassName:傳入一個代理的類名字符串
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

        // NSStringFromClass:反射機制
        // 把類名的字符串轉換成類名Class
//        NSClassFromString(<#NSString *aClassName#>)
        // 好處: 1.防止寫錯 2.有提示

    }
}

// main -> UIApplicationMain -> 通知代理程序啓動完成

// UIApplicationMain底層實現
/*
 1.創建UIApplication對象
 2.創建UIApplication對象代理,設置爲UIApplication對象的代理
 3.開啓主運行循環,目的:保持程序一直運行
 4.加載info.plist文件,判斷下是否指定了main

 // 表示程序啓動完成,纔會通知代理。

 */

發佈了52 篇原創文章 · 獲贊 26 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章