详解iOS应用程序的启动过程

关键步骤

一个程序从main函数开始启动。

int main(int argc, char * argv[]) {

    @autoreleasepool {

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

    }

}


可以看到main函数会调用UIApplicationMain函数,它的四个参数的意思是:

  • argc: 代表程序在进入main函数时的参数的个数。默认为1。
  • argv: 代表包含的各个参数。默认为程序的名字。
  • principalClassName: UIApplication或者它的子类的名字, 如果传入的是nil, 则表示UIApplication的名字, 即@"UIApplication"。
  • delegateClassName: UIApplication的代理的名字。

在UIApplicationMain函数中,根据传入的UIApplication名称和它的代理的名称,会主要做下面的事情:

  • 根据传入的名称创建UIApplication对象。
  • 根据传入的代理名称创建UIApplication代理对象。
  • 开启事件循环(如果不进行循环,那么在main函数结束后程序就结束了。要保证程序创建后可以一直存在)。
  • 解析Info.plist文件:

会在Info.plist文件里查找Main storyboard file base name这个Key对应的Value是否有值。如果有值,则表示之后会通过Storyboard加载控制器,AppDelegate会接收到didFinishLaunchingWithOptions消息(程序启动完成的时候),此时Storyboard会进行一系列的加载操作(后面会具体说);如果没有值,则不会通过Storyboard加载控制器,接着AppDelegate会接收到didFinishLaunchingWithOptions消息(程序启动完成的时候),在这个时候需要我们通过代码的方式加载控制器。

注意Info.plist中Main storyboard file base name这个Key并不是真正的Key,而是苹果为了增强可读性才这样写的,真正的Key为UIMainStoryboardFile(可以通过Info.plist文件的源代码查看)。

这就是在想要用代码方式创建控制器而不是Storyboard创建控制器的时候为什么先要将Main Interface设置为空白,这样在解析Info.plist文件的时候才会知道不通过Storyboard创建控制器。

由此可以知道,解析Info.plist文件这一操作主要是看我们用的是Storyboard方式加载还是代码的方式加载。默认Main storyboard file base name为Main,也就是通过Storyboard方式加载控制器。

现在具体分析一下,通过Storyboard方式加载控制器和代码方式加载控制器。

通过Storyboard

通过Storyboard,主要做了下面的事情(这些事情不需要我们做,是系统自动完成的,在程序启动完成的时候):

创建窗口。

创建一个UIWindow的实例用来显示界面。

设置窗口的根控制器。

根据Storyboard的设置,创建一个控制器。

并且设置这个控制器为之前创建的window的根控制器。

显示窗口。(相当于后面提到的makeKeyAndVisible)

设置self.window可见并且设置UIApplication的keyWindow。

在这一步中将根控制器的view添加到window上。

通过代码方式

通过代码的方式,需要我们在didFinishLaunchingWithOptions方法中进行加载控制器的相关操作。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

    UIViewController *viewController = [[UIViewController alloc] init];

    self.window.rootViewController = viewController;

    // 此时根控制器的view还没有加到self.window上

    [self.window makeKeyAndVisible];

    // 此时根控制器的view加到self.window上

    return YES;

}

以上是 详解iOS应用程序的启动过程 的全部内容, 来源链接: utcz.com/z/330117.html

回到顶部