美文网首页iOS Developer
iOSApp启动原理解析(一)main.m

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

作者: 找不到工作的iOS | 来源:发表于2017-08-24 15:19 被阅读380次

    app程序入口main

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

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

    #import <UIKit/UIKit.h>
    #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的官方描述可以了解到
    D66737BE-74DE-47D9-8BCE-0893851252A2.png
    执行顺序如下:
    1.创建一个application对象
    2.设置了代理
    3.创建了一个事件循环(Runloop,第二篇分析源码)
    4.读取info.plist文件(只读)
    5.创建了一个window
    6.加载第一个控制器 (默认是Main故事版)
    

    UIApplicationMain参数的意义

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

        本文链接:https://www.haomeiwen.com/subject/aoysdxtx.html