为什么不在 Swift 中使用基于结构的单例
Why not use a struct-based singleton in Swift
为什么不使用基于结构的单例?
我创建了可解码的基于结构的单例。
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
}
}
}
像这样从其他 class 初始化:
Person.shared.initData(from: data)
并使用参数:
let name = Person.shared.name
Person.shared.name = "MyName" //error
Person.shared.age = 20
这是不是走错了?
您不能对单例使用结构,因为 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
的类型更改为 class 这是一个引用类型然后 运行 相同的代码打印的结果是
2 2
因为是同一个实例,所以我们更改了 value
属性 for.
为什么不使用基于结构的单例?
我创建了可解码的基于结构的单例。
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
}
}
}
像这样从其他 class 初始化:
Person.shared.initData(from: data)
并使用参数:
let name = Person.shared.name
Person.shared.name = "MyName" //error
Person.shared.age = 20
这是不是走错了?
您不能对单例使用结构,因为 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
的类型更改为 class 这是一个引用类型然后 运行 相同的代码打印的结果是
2 2
因为是同一个实例,所以我们更改了 value
属性 for.