如果我有一些东西看起来像
class Foo {
static shared = Foo()
init() {
print("init Foo")
let _ = Bar.shared
}
}
class Bar {
static shared = Bar()
init() {
print("init Bar")
let _ = Foo.shared
}
}
// somwehere else:
let _ = Foo.shared
则应用程序卡住。什么也不会发生。我知道这个设计是错误的,但我想知道为什么应用程序没有崩溃,报告错误或至少打印一个循环。以上代码打印
init Foo
init Bar
就是这样,表明它没有循环,只是卡住了。知道发生了什么吗?
在Swift中,静态类型属性是以一种保证线程安全的方式惰性初始化的。
Type Properties
存储类型属性在第一次访问时惰性初始化。它们保证只初始化一次,即使在由多个线程同时运行,不需要标记使用惰性修饰符。
这个只有一次特性利用了类似dispatch_once
的东西(或者就是它本身),需要互斥。
初始化Foo.shared
时,Foo.shared
的锁被锁定。当它被锁定时,Bar.shared
需要被初始化,因此Bar.shared
的锁被锁定。当两个都被锁定时,Foo.shared
需要初始化,但是它的锁已经被锁定了,所以在那里等待直到锁被释放…