Setting lazy static variable first initializes then assigns?

时间秒杀一切 提交于 2020-01-14 19:44:21

问题


I realize that static variables are implicitly lazy, which is really great. Doing the below will not create the instance until it's first called:

static var test = Test()

However, assigning a new instance to the static variable initializes the original, then assigns the new instance which is troubling for me:

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

To give more context on what I'm trying to do, I'm trying to setup a pure Swift dependency injection using this article. It's not working so well when swapping the types out in my unit tests because the original type always gets initialized when assigning the mock type.

Here's a more fuller, playground sample:

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

How can I make MyMap.prop1 = MyMock() not first initialize the original MyClass first?


回答1:


You need lazy loading. Try this:

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

Or this:

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


来源:https://stackoverflow.com/questions/43373932/setting-lazy-static-variable-first-initializes-then-assigns

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!