将变量与 UserDefaults 同步的正确方法
Right way to sync a variable with UserDefaults
我想在设置值时直接与 UserDefaults 保持变量同步。我是这样做的:
var userId: String {
get {
return UserDefaults.standard.string(forKey: kUserIdKey) ?? ""
}
set {
UserDefaults.standard.set(newValue, forKey: kUserIdKey)
}
}
它运行良好,但这样做是否正确?
如果是这样,数组呢?
var tagsList: [Int] {
get {
return (UserDefaults.standard.object(forKey: kTagsList) as? [Int]) ?? [Int]()
}
set {
UserDefaults.standard.set(newValue, forKey: kTagsList)
}
}
如果我添加一个元素 tagsList.append(0)
,新值是否存储在 UserDefaults 中?
更新。
这是我在操场上的东西:
简答:是。
长答案:数组和字符串是 Swift 中的 struct
,它们在变异时语义上会生成一个全新的副本。
因此,setter 中的 newValue
是您对数组应用的任何变异的结果数组,无论它是 append
还是其他变异函数。
您可以像这样在 playground 中轻松验证此行为:
var array: [Int] {
get { return [1, 2, 3] }
set { print(newValue) }
}
array.append(4)
// Prints [1, 2, 3, 4]
If I add an element tagsList.append(0), is the new value stored in UserDefaults?
是。
乍一看,你有一个 setter 并且,作为一个 setter,它只会在你进行新分配时观察值,例如:
tagsList = [1,2,3]
// 新值。
如果 Array<Int>
([Int]
) 是 class 我们可以说,即使您确实通过调用 append
修改了现有数组,这也不是赋值, 本身。但是,[Int]
不是 class
,它是 struct
,这意味着任何修改( 突变 的函数都是正确的)现有 struct
,基本上会导致一个新的任务。这就是为什么您会看到 setter 触发的原因。
我想在设置值时直接与 UserDefaults 保持变量同步。我是这样做的:
var userId: String {
get {
return UserDefaults.standard.string(forKey: kUserIdKey) ?? ""
}
set {
UserDefaults.standard.set(newValue, forKey: kUserIdKey)
}
}
它运行良好,但这样做是否正确?
如果是这样,数组呢?
var tagsList: [Int] {
get {
return (UserDefaults.standard.object(forKey: kTagsList) as? [Int]) ?? [Int]()
}
set {
UserDefaults.standard.set(newValue, forKey: kTagsList)
}
}
如果我添加一个元素 tagsList.append(0)
,新值是否存储在 UserDefaults 中?
更新。
这是我在操场上的东西:
简答:是。
长答案:数组和字符串是 Swift 中的 struct
,它们在变异时语义上会生成一个全新的副本。
因此,setter 中的 newValue
是您对数组应用的任何变异的结果数组,无论它是 append
还是其他变异函数。
您可以像这样在 playground 中轻松验证此行为:
var array: [Int] {
get { return [1, 2, 3] }
set { print(newValue) }
}
array.append(4)
// Prints [1, 2, 3, 4]
If I add an element tagsList.append(0), is the new value stored in UserDefaults?
是。
乍一看,你有一个 setter 并且,作为一个 setter,它只会在你进行新分配时观察值,例如:
tagsList = [1,2,3]
// 新值。
如果 Array<Int>
([Int]
) 是 class 我们可以说,即使您确实通过调用 append
修改了现有数组,这也不是赋值, 本身。但是,[Int]
不是 class
,它是 struct
,这意味着任何修改( 突变 的函数都是正确的)现有 struct
,基本上会导致一个新的任务。这就是为什么您会看到 setter 触发的原因。