我想在设置值时直接与UserDefaults保持变量同步。我已经这样做了:
var userId: String {
get {
return UserDefaults.standard.string(forKey: kUserIdKey) ?? ""
}
set {
UserDefaults.standard.set(newValue, forKey: kUserIdKey)
}
}
工作正常,但这是正确的方法吗?
如果是这样,那么Array呢?
var tagsList: [Int] {
get {
return (UserDefaults.standard.object(forKey: kTagsList) as? [Int]) ?? [Int]()
}
set {
UserDefaults.standard.set(newValue, forKey: kTagsList)
}
}
如果我添加元素tagsList.append(0)
,新值是否存储在UserDefaults中?
更新即可。
答案 0 :(得分:2)
简短回答:是的。
答案很长:Swrays中的数组和字符串是struct
,在变异时语义上会创建一个全新的副本。
因此,setter中的newValue
是您应用于数组的任何突变的结果数组,无论它是append
还是其他突变函数。
您可以在这样的游乐场轻松验证此行为:
var array: [Int] {
get { return [1, 2, 3] }
set { print(newValue) }
}
array.append(4)
// Prints [1, 2, 3, 4]
答案 1 :(得分:2)
如果我添加一个元素tagsList.append(0),新值是否存储在UserDefaults中?
是。
乍一看,你有一个setter,作为一个setter,它只会在你做一个新的任务时观察到这个值,比如:
tagsList = [1,2,3]
//新值。
如果Array<Int>
([Int]
)是类,我们可以说,即使您通过调用append
来修改现有数组,这本身也不是一项任务。但是,[Int]
不是class
,它是struct
,这意味着任何修改(变异,正确)现有struct
的函数,基本上会导致新的任务。这就是为什么你会看到setter被触发的原因。