大家在学习iPhone开发时候,都会写HelloWorld程序。大家一般都是通过向导,生成项目,然后通过模拟器启动应用程序。但是大家知道其背后的启动过程吗?也就是当点击程序图标启动程序开始到退出程序整个使用运行过程中底下的代码都发生了什么?有理解了这个才能游刃有余的掌握iPhone程序的开发,否则在写程序的时候有点浑浑僵僵不知所以然的感觉。
在开始介绍HelloWorld程序之前,我们先了解下UIApplication:
UIApplication
UIApplication的核心作用是提供了iOS程序运行期间的控制和协作工作。
UIApplication的一个主要工作是处理用户事件,它会起一个队列,把所有用户事件都放入队列,逐个处理,在处理的时候,它会发送当前事件到一个合适的处理事件的目标控件。此外,UIApplication实例还维护一个在本应用中打开的window列表(UIWindow实例),这样它就可以接触应用中的任何一个UIView对象。UIApplication实例会被赋予一个代理对象UIApplicationDelegate,以处理应用程序的生命周期事件(比如程序启动和关闭)、系统事件(比如来电、记事项警告)等等。
每一个程序在运行期必须有且仅有一个UIApplication(或则其子类)的一个实例。你可以通过调用[UIApplication sharedApplication]来得到这个单例实例的指针。
HelloWorld程序
打开项目文件,找到Other Sources文件夹下的main.m源文件,打开,你将会看到如下代码:
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
和所有的C程序一样,这是个程序入口main函数(NSAutoreleasePool内存自动回收池,不在这篇文章讨论的范围)。接下来我们来看UIApplicationMain函数,查看iPhone开发文档:
UIKIT_EXTERN int UIApplicationMain(int argc, char *argv[], NSString * __nullable principalClassName, NSString * __nullable delegateClassName);
UIKIT_EXTERN int UIApplicationMain(int argc, char *argv[], NSString * __nullable principalClassName, NSString * __nullable delegateClassName);
第三个参数,是UIApplication或者是其子类名,如果是nil,则就默认使用UIApplication类名。
第四个参数是协议UIApplicationDelegate的实例化对象名,如果是nil,则从main nib文件中加载委托对象。这个对象就是UIApplication对象监听到系统变化的时候通知执行的相应方法。
helloWorldappDelegate实现了UIApplicationDelegate协议,可以重写其所有方法。
UIApplicationMain函数中做了哪些事情:
1> 创建了UIApplication对象
2> 创建了UIApplication的delegate对象--appDelegate
3> 开启一个消息循环---每监听到对应的系统事件时,就会通知appDelegate
4> 为应用程序创建一个UIWindow对象(继承自UIView),设置appDelegate的window属性
5> 加载Info.plist文件,读取最主要storyboard文件的名称
6> 加载最主要的storyboard文件,创建白色箭头所指的控制器对象
7> 并且设置第6步创建的控制器为UIWindow的rootViewController属性(根视图控制器)
8> 展示UIWindow,展示之前会将添加rootViewController的view到UIWindow上面(在这一步才会创建控制器的view),[window addSubview:window.rootVIewController.view];
进入main函数,在main.m的main函数中执行UIApplication这个方法,这是ios程序的入口。
我们在打开helloWordApplicationDelegate文件,我们会看到这样的代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = [[ViewController alloc] init];
[self.window makeKeyAndVisible];
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = [[ViewController alloc] init];
[self.window makeKeyAndVisible];
return YES;
}
我们知道,每个应用程序有个UIWindow,这window负责管理和协调应用程序的屏幕显示。在这里把HelloWorldViewController实例赋值给window的rootViewController,rootViewController的view将会作为UIWindow的首视图。
我们知道,每个应用程序有个UIWindow,这个Window负责管理和协调应用程序的屏幕显示。在这里把HelloWorldViewController实例赋值给Window的rootViewController,rootViewController的View将会作为Window的首视图。然后,我们就可以在HelloWorldViewController的init和loadView添加我的数据和控件了。
至此,HelloWord程序启动过程以及介绍完成,大家对程序的启动过程有没有新的认识?
总结程序启动的过程如下:
1. 程序入口main函数创建UIApplication实例和UIApplication代理实例。
2. 在UIApplication代理实例中重写启动方法,设置第一ViewController。
3. 在第一ViewController中添加控件,实现应用程序界面。