iOSApp启动原理解析(一)main.m

app程序入口main

  • 在我们开始开发app的时候,第一步往往是通过设置AppDelegate.m 的代理方法开始写一些启动的东西
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
    然后再通过控制器ViewController.m
    - (void)viewDidLoad;实现一些布局

  • 那么在这些步骤之前做了什么呢?真正的app程序入口是通过工程根目录下Supporting Files里的main.m执行的

#import 
#import "AppDelegate.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        
               return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

1.了解UIApplicationMain方法

  • 通过日常的开发,大家可以猜测到UIApplicationMain执行的是一个死循环方法,验证代码如下:
int main(int argc, char * argv[]) {
    @autoreleasepool {
        NSLog(@"开始运行app");
        UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        NSLog(@"app结束"); //@"app结束"永远不会被执行
        return 0;
       }
}
  • 通过UIApplicationMain的官方描述可以了解到
iOSApp启动原理解析(一)main.m_第1张图片
D66737BE-74DE-47D9-8BCE-0893851252A2.png
执行顺序如下:
1.创建一个application对象
2.设置了代理
3.创建了一个事件循环(Runloop,第二篇分析源码)
4.读取info.plist文件(只读)
5.创建了一个window
6.加载第一个控制器 (默认是Main故事版)

UIApplicationMain参数的意义

  • 通过修改参数可以进入自己创建AppDelegate
#import 
#import "AppDelegate.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        
       return UIApplicationMain(argc, argv, nil, NSStringFromClass([CustomAppDelegate class]));
    }
}
  • UIApplicationMain中的nil参数默认为系统的UIApplication
    所以可以通过修改nil参数,实现进入自己定义的UIApplication类,如下
#import 
#import "AppDelegate.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        
       return UIApplicationMain(argc, argv, @"wfCustomApplication", NSStringFromClass([CustomAppDelegate class]));
    }
}

2.info.plist与启动

  • 通过info.plist的key Main storyboard file base name寻找是否Main,有则进入Main storyboard.
  • 如果没有给值,则跳转至自己设置在keywindowViewController
  • 如果没有给值,也没有在window上设置控制器,那么启动app失败,进入黑屏模式
  • 如果设置了Main,又在window上设置了别的控制器。那么在一个app上会存在两个window,会存在潜在的bug

总结

  • UIApplicationMain底层实现:
    根据principalClassName传递的类名创建UIApplication对象
    创建UIApplication代理对象,给UIApplication对象设置代理
    开启主运行时间循环Runloop,处理事件,保持程序一直运行
    加载info.plist,判断下是否指定了main,如果指定了,就会去加载

你可能感兴趣的:(iOSApp启动原理解析(一)main.m)