Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 两个相互引用的单例阻止初始化结束_Swift_Singleton - Fatal编程技术网

Swift 两个相互引用的单例阻止初始化结束

Swift 两个相互引用的单例阻止初始化结束,swift,singleton,Swift,Singleton,我有一种情况,我希望有两个单例对象,它们彼此持有引用 ManagerA: import Foundation class ManagerA: NSObject { static let sharedInstance = ManagerA() let managerB = ManagerB.sharedInstance private override init() { super.init() } } ManagerB(本例中与Manag

我有一种情况,我希望有两个单例对象,它们彼此持有引用

ManagerA:

import Foundation

class ManagerA: NSObject {

    static let sharedInstance = ManagerA()

    let managerB = ManagerB.sharedInstance

    private override init() {
        super.init()
    }
}
ManagerB(本例中与ManagerA对称):

正在AppDelegate中创建管理器A。 不幸的是,这导致ViewController不再显示,因此我假设初始化过程是无止境的

如何解决初始化问题


我想保持这种模式。这两个管理器在应用程序中的各个位置都有使用,单例模式似乎很适合。不过,如果它们也可以直接访问彼此,这将非常有用。

是的,这是无限递归

你可以用几种方法解决这个问题

在这里,我将这两个属性中的一个作为计算属性,看

final class ManagerA {
    static let sharedInstance = ManagerA()
    var managerB = { return ManagerB.sharedInstance }
    private init() { }
}

final class ManagerB {
    static let sharedInstance = ManagerB()
    let managerA = ManagerA.sharedInstance
    private init() { }
}
更多 然而,您真的需要一个属性来引用一个单例吗?单例的美妙之处在于,只要编写
ClassName.sharedInstance
,就可以从任何地方检索到类的唯一允许实例

因此,您可以轻松删除
managerA
managerB
属性

我做了一些改变
  • 我删除了
    NSObject
    东西,因为你并不真的需要它,不是吗
  • 我将您的类设置为final,否则可能会有人对它们进行子类化,添加init并打破单例范例

@ColGraff:谢谢你的评论。我使用了计算属性而不是弱存储属性,因为在第二种情况下仍然存在无限递归。这对我来说太早了,我在你评论之前就意识到了这一点@科尔格拉夫:没问题;)不过,总的来说,您是对的,
(或
无主
)是管理(并发出信号)您正在避免强引用循环的最佳方式。感谢您提供这一漂亮而干净的解决方案!缺少的一点是第三行中的一个
()
,用于实际计算属性
managerB
…的闭包,或者更确切地说,从那时起,它与最初的闭包是相同的。隐马尔可夫模型。。因此,需要对属性进行求值才能访问,如
managerB().doSomething()
final class ManagerA {
    static let sharedInstance = ManagerA()
    var managerB = { return ManagerB.sharedInstance }
    private init() { }
}

final class ManagerB {
    static let sharedInstance = ManagerB()
    let managerA = ManagerA.sharedInstance
    private init() { }
}