今天我们来介绍一下@NSApplicationMain@UIApplicationMain

用法

回想一下我们在 XCode 中创建一个基于 Objective-C 的 iOS 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]));
}
}

简单解释一下这段代码的作用:

  • main 函数与 C 语言中的入口函数含义是一样的。表示整个 app 的入口。
  • @autoreleasepool 建立了一个自动释放池,用于匹配内存管理中的 ARC 机制。更多的解释,可以看看喵神的 Tips:@AUTORELEASEPOOL。这里不展开讨论。
  • UIApplicationMain函数是整个 app 的启动函数, 函数解释如下:

接收 main 传入的2个参数,直接透传下去,进行一些处理。

根据传入的第三个参数创建UIApplication对象,如果传入 nil, 则创建一个默认的UIApplication对象。

根据传入的第四个产生创建UIApplication对象的代理,赋值给UIApplication的 delegate 属性,用于在程序处于各种状态下,去做一下响应的处理,对应的默认类就是AppDelegate, 用的最多的代理方法是,表示程序加载完成后调用:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

接着会建立应用程序的Main Runloop(事件循环),进行事件的处理。

程序正常退出时UIApplicationMain函数才返回。

以上基于 OC 的 iOS 项目的入口代码。那么在 Swift 的项目中,是不是一样的呢?这里就会引入@NSApplicationMain@UIApplicationMain2个特性。
苹果对 Swift 的项目进行了简化,使用@NSApplicationMain 放在 OSX 桌面应用工程代理类前面,使用@UIApplicationMain放在 iOS app 工程代理类前面。与 OC 工程中的main.m的功能一模一样。这里我们使用 iOS app作为例子,@NSApplicationMain 在 OSX 桌面应用工程里面的用法是一样的, 当你使用Xcode 创建一个 Swift iOS 工程时,自动生成的 AppDelegate.swift 里面,会看到以下代码:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
...

大家平时可以忽悠这个特性点,因为 Xcode 已经自动帮你加上了。不用自己添加任何东西,只需要关注代理类中要去实现的相关的业务逻辑。但是对这个特性的理解,有助于你去理解整个 app 的生命周期。

另外,这篇文章还提到了如何使用自建的main.swift去替代@ UIApplicationMain@NSApplicationMain。回归到 OC 的实现模式去。

stackoverflow 相关问题整理

参考资料

文章目录
  1. 1. 用法
  2. 2. stackoverflow 相关问题整理
  3. 3. 参考资料