iOS 在没有失败的情况下卡在实例化依赖中

iOS get stuck in instantiation dependency without failing

如果我有类似的东西

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

Stored type properties are lazily initialized on their first access. They are guaranteed to be initialized only once, even when accessed by multiple threads simultaneously, and they do not need to be marked with the lazy modifier.

这个只有一次特性利用了需要互斥的dispatch_once-like事物(或者完全是它本身)。

初始化Foo.shared时,Foo.shared的锁被锁定。当它被锁定时,Bar.shared 需要被初始化,所以 Bar.shared 的锁被锁定。虽然两者都被锁定,但 Foo.shared 需要初始化,但它的锁已经被锁定,所以请等待直到锁被释放...

我们称这种情况为死锁