今天我们来介绍一下 @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