今天我们来介绍一下 @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 和 @UIApplicationMain 2个特性。
苹果对 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 的实现模式去。
Is @NSApplicationMain documentation for swift correct?
问题是 @NSApplicationMain 和 NSApplicationMain(_:_:) 的对应关系。官方文档说的没错。
What is use of @NSApplicationMain in swift programming project in xcode
What does “@UIApplicationMain” mean?
以上2个问题都是关于此特性点的含义的疑问,就不多说了。上面已经说的比较详细啦。
Replace @NSApplicationMain or @UIApplicationMain with main.swift
iOS开发UI篇—程序启动原理和UIApplication