用UserDefaults同步变量的正确方法

用UserDefaults同步变量的正确方法

问题描述:

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

+0

你尝试调试它,并检查看起来'newValue'? –

简短的回答:是的。

长答案:数组和字符串在Swift中是struct,它在语义上在变异时会产生一个全新的副本。

因此,setter中的newValue是您应用于该数组的任何突变的结果数组,无论它是否为append或其他变异函数。

您可以轻松地在这样的操场上验证此行为:

var array: [Int] { 
    get { return [1, 2, 3] } 
    set { print(newValue) } 
} 

array.append(4) 
// Prints [1, 2, 3, 4] 

如果我添加元素tagsList.append(0),是存储在UserDefaults新的价值?

是的。

一目了然,你有一个setter和,作为二传手,只观察到,每当你犯了一个新的任务,如值:

tagsList = [1,2,3] //新的价值。

如果Array<Int>[Int])是类,我们可以说,即使您通过调用append来修改现有数组,但这本身并不是一项任务。然而,[Int]不是class,它是struct,这意味着任何修改(变异为,是正确的)现有struct的函数基本上会导致新的赋值。这就是为什么你会看到setter触发的原因。