这篇文章我是基于Swift 3下写的,有些东西,可能会跟之前版本有些出入,不过影响不大
从我们一开始学C语言的时候,就知道main()
函数是一个程序的entry point
,这是约定俗成的东西,当然,iOS APP 也不例外。
之前我们用Xcode新建一个项目,选择Objective-C作为开发语言,建成的工程里面除了AppDelegate.m
、Main.storyboard
等再熟悉不过的文件,还有一个main.m
,既熟悉又陌生。
int main(int argc, char * argv[]) {
@autoreleasepool {
MCSLog(@"%s", argv[0]);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
同样的,这也是我们一个iOS 程序的入口,调用UIApplicationMain
函数注册了Application代理,开始了事件循环。
不过,当我们新建一个Swift
工程的时候,细心的同学就会发现,找不到我们熟悉的main.swift
文件了,同时我们也会在AppDelegate.swift
里,发现一个@UIApplicationMain
Attribute。
官方文档这么描述的:
UIApplicationMain
Apply this attribute to a class to indicate that it’s the application delegate.
Using this attribute is equivalent to calling the UIApplicationMain function and passing this class’s name as the name of the delegate class.
还有Stack上的回答也很详细,建议看看。
原来,@UIApplicationMain
就是为了取代我们在OC项目中的main.m
,它实现了main函数(程序入口)以及调用了Cocoa Touch上的UIApplicationMain 函数,开启事件循环。
应用了这个 UIApplicationMain Attribute
也就表明,当前类作为application的代理,也就等同于这个函数的调用UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
因此,你也可以简单认为,AppDelegate.swift
跟main.swift
通过这个Attribute合并为一体了,AppDelegate.swift
也成为initial entry file
.
那么,你自己新建MyAppDelegate.swift
,然后Apply @UIApplicationMain,同样也是可以的
// 使用@UIApplicationMain,必须要遵循UIApplicationDelegate,不然编译器会报如下错误
// 'UIApplicationMain' class must conform to the 'UIApplicationDelegate' protocol
@UIApplicationMain
class MyAppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
}
到这里,可能有些同学就会问,那我自己建个main.swift
文件呢?当然可以!
新建一个main.swift
,这里注意一点,文件名称必须是main.swift
, 然后实现如下:
import UIKit
import Foundation
// Swift 2 使用Process.argc
let argc = CommandLine.argc // Swift 3 把 Process改为CommandLine 了
let argv = UnsafeMutablePointer<UnsafeMutablePointer<Int8>>.allocate(capacity: Int(CommandLine.argc))
// let argv = UnsafeMutableRawPointer(CommandLine.unsafeArgv).bindMemory(to: UnsafeMutablePointer<Int8>.self, capacity: Int(CommandLine.argc))
UIApplicationMain(argc, argv, nil, NSStringFromClass(AppDelegate.self))
这里注意一点:如果你自己创建了main.swift
,那么记得把@UIApplicationMain
去掉,不然会报错
'UIApplicationMain' attribute cannot be used in a module that contains top-level code
@UIApplicationMain 只是在iOS上,Mac OS上相应的是@NSApplicationMain