【问题标题】:Why not use a struct-based singleton in Swift为什么不在 Swift 中使用基于结构的单例
【发布时间】:2021-12-06 21:53:58
【问题描述】:

为什么不使用基于结构的单例?

我创建了可解码的基于结构的单例。

struct Person: Decodable {
    static var shared = Person()

    private(set) var name: String?
                 var age: Int?
   
    private init() {
    
    }

    mutating func initData(from data: Data) {
        if let person = try? JSONDecoder().decode(Person.self, from: data) {
            self = person
        }
    }
}

像这样从其他类初始化:

Person.shared.initData(from: data)

并使用参数:

let name = Person.shared.name 
Person.shared.name = "MyName" //error


Person.shared.age  = 20

这是错误的方式吗?

【问题讨论】:

    标签: swift struct singleton swift5


    【解决方案1】:

    您不能为单例使用结构,因为struct 是一种值类型,因此当您将其分配给变量时,您会得到一个副本。这很容易显示

    struct Singleton {
        static var shared = Singleton()
        var value: Int
    
        private init() {
            value = 0
        }
    }
    
    Singleton.shared.value = 1
    var otherSingleton = Singleton.shared
    otherSingleton.value = 2
    

    现在如果我们打印两者的value

    print(Singleton.shared.value, otherSingleton.value)
    

    我们得到

    1 2

    所以otherSingleton 显然是一个单独的实例,所以现在我们有 2 个单例 :)

    但是如果我们简单地将Singleton 的类型更改为引用类型的类,然后运行相同的代码,打印的结果是

    2 2

    因为它是同一个实例,所以我们更改了 value 属性。

    【讨论】:

    • 如果我不创建和使用单独的实例,是否可以使用基于结构的单例?
    • @user16114557 是的,如果你从不做错任何事,你可以做任何事情;)首先使用单例的关键是你不能错误地创建多个实例,这很容易发生,也许不是今天,而是将来的某个时候。此外,如果你“知道”你永远不会犯这个错误,那么你真的不需要单例,那么使用 shared 就足够了。
    • 这很有帮助。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2018-01-14
    • 2018-07-10
    • 2021-08-13
    • 1970-01-01
    • 2016-06-16
    • 2020-03-20
    • 2017-08-14
    • 1970-01-01
    相关资源
    最近更新 更多