iOS会陷入实例化依赖而不会失败



如果我有一些东西看起来像

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需要初始化,但是它的锁已经被锁定了,所以在那里等待直到锁被释放…

我们称这种情况为死锁

最新更新