使用UserDefaults同步变量的正确方法

时间:2017-10-18 07:57:48

标签: ios swift swift3 userdefaults

我想在设置值时直接与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中?

更新即可。

以下是我在操场上的内容: enter image description here

2 个答案:

答案 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被触发的原因。