【问题标题】:Setting lazy static variable first initializes then assigns?设置惰性静态变量首先初始化然后分配?
【发布时间】:2017-04-12 15:35:13
【问题描述】:

我意识到static 变量隐含地是lazy,这真的很棒。在第一次调用之前,执行以下操作不会创建实例:

static var test = Test()

但是,将新实例分配给 static 变量会初始化原始实例,然后分配给我带来困扰的新实例:

SomeType.test = AnotherTest() //Initializes Test then AnotherTest type

为了提供更多关于我正在尝试做的事情的背景信息,我正在尝试使用 this article 设置一个纯 Swift 依赖注入。在我的单元测试中换出类型时效果不佳,因为在分配模拟类型时总是会初始化原始类型。

这是一个更完整的游乐场示例:

protocol MyProtocol { }

class MyClass: MyProtocol {
    init() { print("MyClass.init") }
}

////

struct MyMap {
    static var prop1: MyProtocol = MyClass()
}

protocol MyInject {

}

extension MyInject {
    var prop1: MyProtocol { return MyMap.prop1 }
}

////

class MyMock: MyProtocol {
    init() { print("MyMock.init") }
}

// Swapping types underneath first initializes
// original type, then mock type :(
MyMap.prop1 = MyMock()

prints: MyClass.init
prints: MyMock.init

如何让MyMap.prop1 = MyMock()不先初始化原来的MyClass

【问题讨论】:

    标签: swift dependency-injection static lazy-initialization


    【解决方案1】:

    您需要延迟加载。试试这个:

    struct MyMap {
        private static var _prop1: MyProtocol?
        static var prop1: MyProtocol {
            get { return _prop1 ?? MyClass() }
            set(value) { _prop1 = value }
        }
    }
    

    或者这个:

    struct MyMap {
        private static var _prop1: MyProtocol?
        static var prop1: MyProtocol {
            get {
                if _prop1 == nil {
                    _prop1 = MyClass()
                }
                return _prop1!
            }
            set(value) { _prop1 = value }
        }
    }
    

    【讨论】:

    • 哇,为什么会这样??!.. 这是 Swift 中的错误还是故意的?
    • 正如 swift 所期望的那样。 var 需要一个值,只要它存在。这个值可以是 nil 或一个具体的值。根据您的定义,您的 var 不能为 nil,因此您必须指定一个值(或编译抛出错误)。调用 get 或 set 并不重要。 Swift 在使用它之前必须确保你的 var 有一个值。这就是苹果所说的“swift is save”。
    • @codealchimist 但是static 存储的属性是延迟加载的——如果它在加载之前首先被分配,它不应该调用属性初始化器。但这只是目前 Swift 的行为方式。
    • 还值得注意的是,static 存储属性初始化器是线程安全的,而像第二个示例中的延迟加载不是线程安全的。
    • @Hamish True 两个 cmets。它也有一个错误报告,也许它会在未来的 swift 版本中发生变化,并且 static 不再是惰性的,或者它可以从惰性 var 中按预期工作。出于兼容性原因,认为它将是第一个。我们会看到..
    猜你喜欢
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 2010-12-22
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    相关资源
    最近更新 更多