我们创建一个 iOS 的程序后,是从 main.m 函数开始执行的,在 main.m 里面是这样的:

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

UIApplicationMain

This function is called in the main entry point to create the application object and the application delegate and set up the event cycle.

UIApplicationMain方法内部是一个消息循环,执行之后程序并没有退出。

Declaration

int UIApplicationMain(int argc, char *argv[], NSString * __nullable principalClassName, NSString * __nullable delegateClassName);

Parameters

第一二个是 main 函数的入参,分别代表参数个数和参数内容;
principalClassName 是 UIApplication class or subclass’s name,如果是 nil,默认就是 UIApplication.
delegateClassName
是应用程序的代理的类的实例的名字,如果 principalClassName 指向 UIApplication 的子类,可以把子类设成应用程序的代理;子类实例会收到应用代理消息,如果从应用程序的 main nib file 中设置 delegate,需要设置成 nil.

Return Value

即使指定了返回类型,函数也是永远不会返回。当用户点击 home 键退出 iOS 程序后,应用程序移到后台。

Discussion

此函数从主类实例化应用程序对象,设置应用程序的代理。初始化了主事件的循环(main event loop),包括应用程序循环,开始处理事件。如果应用程序的 Info.plist 指定加载一个 nib file,通过设置 NSMainNibFile key 和有效的 nib名字,函数就会从这个 nib 中加载。

关于 iOS 程序中 main 函数之前发生了什么?
比如+ load 方法是在 main 函数执行之前的
dyld(the dynamic link editor)动态链接器
dyld 在完成环境的初始化后,配合 ImageLoader 将二进制文件按格式加载到内存,动态链接依赖库,并由 runtime 加载 objc 定义的结构,在初始化结束后,dyld 调用真正的 main 函数。
更具体的可以见这篇 blog