tldr;为什么我们总是使用UserDefaults.standard
而不是子类化UserDefaults来制作更符合我们需求的东西呢?
之前有没有人将UserDefaults子类化?或者这被认为是不好的做法?
例如,假设我们创建了UserDefaults的ColorDefaults子类。当应用程序,ColorDefaults对象被实例化,对象加载它自己的所有数据。然后,加载的数据可以通过委托发送到适当的对象,或通过单例普遍提供。
我的运行理论是,UserDefaults仅用于存储相对数量的数据,因此必须使用单例强制执行该想法。
结论:我们使用UserDefaults.standard
是因为:
答案 0 :(得分:2)
您的ColorDefaults
不应该是UserDefaults
的子类。它应该是一个普通的结构或类,其计算属性由UserDefaults
支持。
以下是使用静态属性的示例,但您可以将其重构为使用单例类。
struct ColorDefaults {
static var someDefault: String {
get {
return UserDefaults.standard.string(forKey: "someKey") ?? "some initial value"
}
set {
UserDefaults.standard.set(newValue, forKey: "someKey")
}
}
}
let someVal = ColorDefaults.someDefault // read
ColorDefaults.someDefault = "hello" // write
如果您的一个默认值更复杂并且需要对UserDefaults
进行编码/解码,这也很有用。逻辑在这里而不是你的应用程序。
请注意,此类只应用于存储少量偏好,而不是用于存储完整的应用数据。
答案 1 :(得分:0)
用户默认值是文件存储系统。除非你想改变它的一些逻辑,否则在子类化中没有什么意义。但是你可以创建多个套装,比如UserDefaults(suiteName: String)
。您希望通过子类化做什么?您可以简单地全局定义let myDefaults = UserDefaults(suiteName: String)
并在任何地方使用它。我想你可以使用像
class MyDefaults: UserDefaults {
func saveName(_ name: String) {
setValue(name, forKey: "name_key")
}
}
但是,再次创建一个扩展
可能更有意义extension UserDefaults {
func saveName(_ name: String) {
setValue(name, forKey: "name_key")
}
}
或者让它更复杂一点:
extension UserDefaults {
struct User {
static let defaults = UserDefaults(suiteName: "User")
static func saveName(_ name: String) {
defaults.setValue(name, forKey: "name")
}
}
struct General {
static let defaults = UserDefaults.standard
static func saveLastOpened(date: Date) {
defaults.setValue(date, forKey: "last_opened")
}
}
}
但所有这些都有一个致命的流程:现在你依赖于在应用程序中使用用户默认值。在某些时候,您可能会发现需要以某种其他形式保存这些数据,例如与iCloud同步的本地JSON文件。我猜UserDefaults.User
可能会被修改,但会非常难看。我们想要的不是UserDefaults.User.saveName("My name")
而是User.saveName("My name")
。从界面的角度来看,我们不关心保存此用户名的位置,如果引入新系统来保存这些数据,我们不希望在界面中进行更改。
换句话说,假设您在应用程序中的100个位置使用UserDefaults.User.saveName
,现在想要使用另一个系统来保存用户名。您现在需要在100个地方更改代码才能使用AnotherSystem.User.saveName
,而如果您只是使用User.saveName
,则界面仍然有效。
所以底线是(广泛地)修改,扩展或子类化UserDefaults
没有任何意义,因为它最好创建一个包装UserDefaults
的系统,以后可能会更改为任何其他系统。
答案 2 :(得分:-1)
好像你正在寻找类似的东西
class ColorDefaults : NSObject
{
/// Save Data
class func saveDataInDefaultForKey(_ key: String, _ data: Any){
UserDefaults.standard.set(data, forKey: key)
}
/// Retrieve data
class func retrieveDataFromDefaultsWithKey(_ key: String) -> Any {
return UserDefaults.standard.value(forKey: key) as Any
}
}
保存并获取数据:
/// Save Data
ColorDefaults.saveDataInDefaultForKey("myArray", myArray)
ColorDefaults.saveDataInDefaultForKey("myString", myString)
/// Get Data
if let valueString = ColorDefaults.retrieveDataFromDefaultsWithKey("myString") as? String {
print("Saved Value String: \(valueString)")
}
else {
print("Error retrieving myString")
}
if let valueArray = ColorDefaults.retrieveDataFromDefaultsWithKey("myArray") as? [String] {
print("Saved Value Array: \(valueArray)")
}
else{
print("Error retrieving myArray")
}
输出: