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

标签 swift instantiation static-variables

如果我有类似的东西

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.

这个 only once 特性利用了类似于 dispatch_once 的东西(或者完全是它本身),它需要互斥。

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

我们称这种情况为死锁

关于swift - iOS 在没有失败的情况下卡在实例化依赖中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39312818/

相关文章:

swift - 采用协议(protocol)时如何避免重复初始化?

python - 在其类定义之后立即实例化 python 对象

ios - 如何获得 [Error] : from NSError. 描述?

ios - 如何从小部件扩展导航到 UIKit viewController?

iOS swift : Store cache using coredata (cloudkit)

c++ - 我应该如何为 DLL 使用此模板函数显式实例化?

Python:动态实例化

java - 将全局静态变量声明为 null 是一个好习惯吗?

c++ - C++类中的静态全局变量

Android:通过静态变量传递值会导致安全问题吗?