iOSApp启动原理解析(一)main.m
2017-08-24 本文已影响380人
找不到工作的iOS
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的官方描述可以了解到
执行顺序如下:
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. - 如果没有给值,则跳转至自己设置在
keywindow
上ViewController
- 如果没有给值,也没有在window上设置控制器,那么启动app失败,进入黑屏模式
- 如果设置了Main,又在window上设置了别的控制器。那么在一个app上会存在两个window,会存在潜在的bug
总结
- UIApplicationMain底层实现:
根据principalClassName传递的类名创建UIApplication对象
创建UIApplication代理对象,给UIApplication对象设置代理
开启主运行时间循环Runloop,处理事件,保持程序一直运行
加载info.plist,判断下是否指定了main,如果指定了,就会去加载