程序啓動及程序的生命週期

一、程序的啓動過程

1.程序一啓動是先要進入main函數的,main函數是程序的默認入口。

/**
 *  程序的入口函數
 */
int main(int argc, char * argv[]) {
    @autoreleasepool {
        
        /**
         *  此函數會創建一個隱式的application對象
         *
         *  @param argc   用戶傳入的參數個數
         *  @param argv   封裝了用戶傳入的多個參數
         *  @param nil    應用程序類,傳nil表示用系統默認的應用程序類
         *  @param class 應用程序類的代理類 可以自定義 比如:[MYAppDelegate class]
         */
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

PS;

在這個方法裏主要完成以下事情

1.

創建UIApplication對象

創建Appdelegate對象,並且成爲UIApplication對象的代理屬性。

開啓主運行循環:目的讓程序一直跑起來,監聽用戶操作和相應事件的調度。主運行循環一旦進入就會創建自動釋放池。

加載info.plist文件,判斷下info.plist文件裏面指定的內容。

假如info.plist裏指定了main.storyboard加載main.storyboard。

2-1:指定了main.storyboard的情況


先初始化窗口UIWindow。

然後加載storyboard文件,創建箭頭指定的控制器。

把新創建的控制器作爲窗口的根控制器,讓窗口實現。

類似下面的實現的代碼:

UIStoryboard* story = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
[story instantiateInitialViewController];
//啓動完畢之後調用下面的方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullableNSDictionary *)launchOptions NS_AVAILABLE_IOS(3_0);

2-2:沒有指定main.storyboard的情況


//啓動完畢之後調用下面的方法
//需要在這個方法裏指定窗口和窗口的根控制器。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions NS_AVAILABLE_IOS(3_0);
啓動過程如下:


二、application對象的代理對象

#import "AppDelegate.h"
#import "MYViewController.h"
#import <AVFoundation/AVFoundation.h>

@interface AppDelegate ()

@property (nonatomic, strong) AVAudioPlayer *player;

@end

@implementation AppDelegate

/**
 *  應用程序一共包括如下幾種狀態
 1、not running 未運行
 2、Inactive 未活動 不接受觸碰事件
 3、active 活動 這是在前臺時所處的正常狀態
 4、Background 後臺 
 5、Suspended 掛起
 *
 */

#pragma mark - 程序啓動時調用
//1、應用程序將要啓動時自動調用該方法,該方法是應用程序啓動時第一次執行自定義代碼的機會
-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    //檢測應用程序的狀態
    /**
     *
     typedef NS_ENUM(NSInteger, UIApplicationState) {
     UIApplicationStateActive,//活動狀態
     UIApplicationStateInactive,//未活動狀態
     UIApplicationStateBackground//後臺狀態
     } NS_ENUM_AVAILABLE_IOS(4_0);
     *
     */
    UIApplicationState state = [UIApplication sharedApplication].applicationState;
    NSLog(@"1state = %ld",(long)state);
    
    
    
    
    return YES;
}

//2、應用程序啓動時自動調用該方法,開發者可以在該方法中執行初始化相關的代碼
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    /**
     *  檢測應用程序的狀態
     */
    UIApplicationState state = [UIApplication sharedApplication].applicationState;
    NSLog(@"2state = %ld",(long)state);
    
    //如果不指定storyboard文件的話就沒有window對象和根視圖控制器 需要在這裏創建
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    //創建根控制器,實際開發中還需要標籤控制器綁定導航控制器,導航控制器綁定視圖控制器
    MYViewController * vc = [[MYViewController alloc] init];
    self.window.rootViewController = vc;
    //設置並顯示主window
    [self.window makeKeyAndVisible];
    return YES;
}

#pragma mark - 程序進入前臺時調用
//3、應用在轉入前臺並進入活動狀態時調用該方法,可重寫該方法執行最後的準備工作(啓動--前臺   後臺--前臺)
- (void)applicationDidBecomeActive:(UIApplication *)application {
    /**
     *  檢測應用程序的狀態
     */
    UIApplicationState state = [UIApplication sharedApplication].applicationState;
    NSLog(@"3state = %ld",(long)state);
    
}

#pragma mark - 程序將要從前臺離開
//4、應用正要從前臺運行狀態離開時將會調用該方法
- (void)applicationWillResignActive:(UIApplication *)application {
    /**
     *  檢測應用程序的狀態
     */
    UIApplicationState state = [UIApplication sharedApplication].applicationState;
    NSLog(@"4state = %ld",(long)state);
    
    
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"後臺播放.mp3" withExtension:nil];
    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
    [player prepareToPlay];
    // 無限播放
    player.numberOfLoops = -1;
    _player = player;
    //進入後臺播放
    [player play];
}

//5、應用來到Background狀態,且隨時可進入Suspended狀態時將會調用該方法
- (void)applicationDidEnterBackground:(UIApplication *)application {
    /**
     *  檢測應用程序的狀態
     */
    UIApplicationState state = [UIApplication sharedApplication].applicationState;
    NSLog(@"5state = %ld",(long)state);
    
}

#pragma mark - 程序從後臺進入前臺時調用
//6、程序正從後臺轉入前臺(啓動時不會調用)運行狀態,但暫時還沒有達到Active狀態時將會調用該方法
- (void)applicationWillEnterForeground:(UIApplication *)application {
    /**
     *  檢測應用程序的狀態
     */
    UIApplicationState state = [UIApplication sharedApplication].applicationState;
    NSLog(@"6state = %ld",(long)state);
    
    //進入前臺停止播放
    [_player stop];
}

#pragma mark - 程序停止時調用
//7、應用程序將要被終止時調用該方法,如果應用當前處在Suspended狀態,此方法將不會被調用
- (void)applicationWillTerminate:(UIApplication *)application {
    /**
     *  檢測應用程序的狀態
     */
    UIApplicationState state = [UIApplication sharedApplication].applicationState;
    NSLog(@"7state = %ld",(long)state);
}

@end



參考文章:

1、UIApplication深入研究 - pengyingh - 博客園

2、iOS中的程序的五種狀態 - [[XXXXalloc]init] - 博客園


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