您可以通过向视图控制器添加“计算”属性来轻松找到:
class TestClass: UIViewController {
let a = {()->Int in print("global initialization"); return 10 }()
}
并添加一个
print("didFinishLaunching")
在应用程序的委托didFinishLaunchingWithOptions 方法中。
你会得到的顺序是
global initialization
didFinishLaunching
这意味着全局初始化程序在应用生命周期开始之前运行。
现在,为了更进一步,您可以添加一个包含以下内容的 main.swift 文件
print("Before UIApplicationMain")
UIApplicationMain(CommandLine.argc, unsafeBitCast(CommandLine.unsafeArgv, to: UnsafeMutablePointer<UnsafeMutablePointer<Int8>>.self), nil, NSStringFromClass(AppDelegate.self))
并从您的 AppDelegate 类中删除(或注释)@UIApplicationMain 装饰。这将指示编译器使用 main.swift 中的代码进行应用程序初始化,而不是讨论中装饰器提供的默认行为(尽管我们提供了几乎相同的自定义实现)。
你会在第二种方法中得到的是
Before UIApplicationMain
global initialization
didFinishLaunching
表示加载情节提要时执行实例属性代码。
现在,为了更深入地了解,让我们尝试找出静态实例变量之间的区别。为此,我们将添加一个测试类:
class PropertyInitializationTest {
static let staticProp = {()->String in print("static initialization of InitializationTest"); return "" }()
let instanceProp = {()->String in print("instance initialization of InitializationTest"); return "" }()
init() {
print("In initializer")
}
}
,并且更新 AppDelegate 确实完成了启动:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
print("didFinishLaunching")
print("before instantiating InitializationTest")
_ = PropertyInitializationTest()
print("after instantiating InitializationTest")
// Override point for customization after application launch.
return true
}
我们得到的输出是:
Before UIApplicationMain
global initialization
didFinishLaunching
before instantiating InitializationTest
instance initialization of InitializationTest
In initializer
after instantiating InitializationTest
,它确认实例属性在类被实例化时以及在任何初始化程序代码运行之前被设置。
但是等等!静态属性呢?没有任何痕迹表明它已被初始化。看起来静态属性在定义上是惰性的,只有在第一次访问时才会被初始化。
更新应用确实完成了启动代码确认了这一点。
print("didFinishLaunching")
print("before instantiating InitializationTest")
_ = PropertyInitializationTest()
print("after instantiating InitializationTest")
_ = PropertyInitializationTest.staticProp
print("after instantiating InitializationTest")
给出以下输出:
Before UIApplicationMain
global initialization
didFinishLaunching
before instantiating InitializationTest
instance initialization of InitializationTest
In initializer
after instantiating InitializationTest
static initialization of InitializationTest
after instantiating InitializationTest
总结:
- 实例属性在类初始化程序运行之前接收编译时值(如果已设置),因此在该类的任何代码执行之前
- 静态属性仅在第一次访问时接收它们的值,它们本质上是惰性的