Launch a iOS app / 应用启动原理

  1. 首先将会启动 main.m
  2. 在其中创建 UIApplication 对象;
  3. 并为其设置代理。

    1
    2
    3
    4
    5
    6
    7
    8
    #import <UIKit/UIKit.h>
    #import "AppDelegate.h"
    int main(int argc, char * argv[]) {
    @autoreleasepool {
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
    }

    argc, argv, nil, NSStringFromClass([AppDelegate class]) 中:

    • nilUIApplication 类或其子类的名称,当传入 nil 时视为传入 @"UIApplication"
    • NSStringFormClass([AppDelegate class]) 为获取 AppDelegate 的类名;
  4. 开始一个主运行循环 (RunLoop),保证 app 运行期间不会退出
  5. 加载 info.plist,如果其中指定有 Main storyboard file base name 则加载对应的 StoryBoard:
    创建⼀一个窗⼝,加载 MainStoryBoard,初始化⼀个控制器,把初始化出来的控制器设置为窗⼝的根控制器.让窗口显示到屏幕上
  6. 如果其中没有指定 Main storyboard file base name (recommened):
    • 窗口必须强引用 @property (strong, nonatomic) UIWindow *window
    • 创建窗口 self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

      Plan A - 手动创建

    • 创建一个控制器 UIViewController *mainViewController = [[UIViewController alloc] init];
    • UIWindow 的根控制器设置为上面创建的控制器 self.window.rootViewController = mainViewController;
      • 为了能看见效果,创建一个带颜色的 UIView 在上面
      • UIView *testView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
      • testView.backgroundColor = [UIColor redColor];
      • [self.window addSubview:testView];
    • 显示出这个 UIWindow [self.window makeKeyAndVisible];

      Plan B - 从 StoryBoard 加载

      • 加载 Main.Storyboard UIStoryboard *mainStoryBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
      • 从中加载箭头指向的控制器 self.window.rootViewController = [mainStoryBoard instantiateInitialViewController];
      • 或者根据 标识 加载指定的控制器 UIViewController *aViewController = [storyBoard instantiateViewControllerWithIdentifier:@"aViewController"];
      • 将其显示出来 [self.window makeKeyAndVisible];
        makeKeyAndVisible 可能的底层实现:
      • self.window.hidden = NO 因为创建出来的 UIWindow 是隐藏的
      • [self.window addSubview:mainViewController.view] 将控制器的 view 添加到 window
      • [UIApplication sharedApplication].keyWindow 将当前窗口设置为应用的主窗口

在自动创建的 AppDelegate.m 中默认实现了以下方法:

  • 当 App 启动完成 / didFinishLaunching 时调用:

    1
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  • 当应用程序将要失去焦点(即不能与用户进行交互时)/ Will Resign Active 时调用

    1
    - (void)applicationWillResignActive:(UIApplication *)application;
  • 当应用程序进入后台 / Did Enter Background 时调用

    1
    - (void)applicationDidEnterBackground:(UIApplication *)application;
  • 当应用程序即将进入前台 / Will Enter Foreground 时调用

    1
    - (void)applicationWillEnterForeground:(UIApplication *)application;
  • 当应用程序获取焦点(即能够与用户进行交互)/ Did Become Active 时调用

    1
    - (void)applicationDidBecomeActive:(UIApplication *)application;
  • 当应用程序被退出 / Will Terminate 时调用

    1
    - (void)applicationWillTerminate:(UIApplication *)application;

另外,当接收到内存警告 /Did Receive Memory Warning 时,会调用

1
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application;