美文网首页
app启动过程分析

app启动过程分析

作者: 木小土 | 来源:发表于2017-05-24 18:41 被阅读285次

    前言

    文章中的观点主要通过阅读苹果官方文档和代码调试结果得出,如有偏差或者遗漏的地方,欢迎留言指出。

    image

    这张图来自于苹果的官方文档,大致描述了app的启动流程,可以先跳过不看。

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

    在Xcode中打开main.m文件,可以看到在main方法中调用了UIApplicationMain方法,这个方法承载了app启动过程中的三个主要工作:

    1. 根据方法的第三个参数,创建UIApplication对象。如果参数为nil, 则使用UIApplication类。这个UIApplication对象会以单例的方式存在于app的整个生命周期,直到app退出;

    2. 根据第四个参数,创建UIApplication Delegate对象;

    3. 创建主事件循环(RunLoop)并启动

    4. 加载info.plist, 如plist文件中配置了StoryBoard, 则加载Storyboard中的view.

    虽然UIApplicationMain有返回值,但是在整个程序运行期间不会返回,只有在app退出时才会返回。

    实践才是检验真理的唯一标准!

    验证一: UIApplication对象和RunLoop对象的创建

    创建一个新的工程,并打开main.m 文件,在main方法体内打上断点
    ,同时在AppDelegate.m的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法体内也打上断点,重新运行一下项目。

    项目会停留在main方法中,在debug窗口中打印UIApllication对象和RunLoop对象

    po [UIApplication sharedApplication] //返回nil
    
    po [NSRunLoop currentRunLoop].currentMode //返回nil
    

    继续执行程序,程序会停留在didFinishLaunchingWithOptions方法体内,在debug窗口中再次打印UIApplication对象和RunLoop对象

    po [UIApplication sharedApplication] //返回<UIApplication: 0x7fa6a8400790>
    
    po [NSRunLoop currentRunLoop].currentMode   //返回UIInitializationRunLoopMode
    

    由此可得出,UIApplication对象和RunLoop事件循环在UIApplicationMain方法中被创建。

    验证二:Storyboard的加载

    Xcode会在新建的工程中自动创建一个Main.storyboard文件,并在info.plist配置好。保留验证一里设置的AppDelegate中设置的断点,重新运行程序,在断点出打印self.window.rootViewController属性

     po self.window.rootViewController //<ViewController: 0x7f986ac08090>
    
    

    由此可见,Main.storyboard在didFinishLaunchingWithOptions回调方法之前已经被自动加载并设置为window的根对象。

    删除info.plist中的Main storyboard file base name这一项,重新运行项目,在didFinishLaunchingWithOptions方法中打印self.window

     po self.window // nil
    
    

    验证三:无论是否有storyboard,didFinishLaunchingWithOptions中回调中都可以设置self.window的rootViewController

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // Override point for customization after application launch.
        
        self.window = [[UIWindow alloc] init];
        self.window.rootViewController = [[ViewController alloc] init];
        [self.window makeKeyAndVisible];
        return YES;
    }
    
    

    分别尝试有storyboard的情况和无storyboard的情况,通过验证可以得出如果有storyboard, UIApplicationMain会先加载storyboard,如果没有,则需要使用代码在didFinishLaunchingWithOptions回调方法里创建self.window对象。

    最后梳理一下app启动过程:

    1. 调用main()方法;

    2. 调用并进入UIApplicationMain()方法, 直到程序退出时方法才会退出。其内部的执行顺序为:

      a. 创建UIApplication对象;

      b. 创建UIApllication的delegate对象;

      c. 加载info.plist文件,如果配置有storyboard文件名,则加载 storyboard;

      d. 开启一个主线程的RunLoop,监听事件。

    现在,可以回头看下苹果的流程图。

    相关文章

      网友评论

          本文标题:app启动过程分析

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