我试图在Swift 2中为一个使用NSUserDefaults
的任何类型的设置实现一个类。
问题:如何定义用于存储和检索任何类型对象的类,包括Dictionary
?
我有一个适用于AnyObject
的解决方案,它由通用协议(Settable
)和通用类(Setting
)组成。 SettingsStore
是NSUserDefaults
的包装。
// MARK: Settable Protocol
public protocol Settable {
typealias T
init(key: String, defaultValue: T, settingsStore: SettingsStore)
var value: T { get set }
func loadCurrentValue()
}
// MARK: Settings Class
public class Setting<T: AnyObject>: Settable {
private let key: String
private let defaultValue: T
private let settingsStore: SettingsStore
private var currentValue: T?
public required init(key: String, defaultValue: T, settingsStore: SettingsStore) {
self.key = key
self.defaultValue = defaultValue
self.settingsStore = settingsStore
}
public var value: T {
get {
if self.currentValue == nil {
self.loadCurrentValue()
}
return self.currentValue!
}
set {
self.currentValue = newValue
self.settingsStore.setObject(newValue.toAnyObject(), forKey: self.key)
}
}
public func loadCurrentValue() {
let optionalValue: T? = self.settingsStore.objectForKey(key) as? T
if let value = optionalValue {
self.currentValue = value
} else {
self.currentValue = self.defaultValue
}
}
}
这允许我创建这样的设置:
let specialId: Setting<String>
init() {
self.specialId = Setting<String>(
key: "specialId",
defaultValue: "<somevalue>",
settingsStore: self.settingsStore)
}
问题在于它无法使用值类型,例如String
,Bool
,Int
,Double
,{{1} }或Array
因为它们都是值类型,而且值类型不符合Dictionary
协议。
我已经使用基于AnyObject
和NSString
的协议和扩展解决了其中一些问题,但解决方案NSNumber
被证明是难以捉摸的(我不知道目前还不需要Dictionary
的解决方案,因此我还没有花时间尝试解决这个问题。)
Array
我为// Change definition of Setting class like this:
public class Setting<T: AnyObjectRepresentable>: Settable {
...
}
public protocol AnyObjectRepresentable {
func toAnyObject() -> AnyObject
static func fromAnyObject(value: AnyObject) -> Self?
}
extension AnyObjectRepresentable where Self: AnyObject {
public func toAnyObject() -> AnyObject {
return self
}
public static func fromAnyObject(value: AnyObject) -> AnyObject? {
return value
}
}
extension String: AnyObjectRepresentable {
public func toAnyObject() -> AnyObject {
return NSString(string: self)
}
public static func fromAnyObject(value: AnyObject) -> String? {
let convertedValue = value as? String
return convertedValue
}
}
extension Bool: AnyObjectRepresentable {
public func toAnyObject() -> AnyObject {
return NSNumber(bool: self)
}
public static func fromAnyObject(value: AnyObject) -> Bool? {
let convertedValue = value as? Bool
return convertedValue
}
}
// Add extensions for Int and Double that look like the above extension for Bool.
尝试了两种不同的方法。第一个类似于Dictionary
方法:
String
Xcode在extension Dictionary: AnyObjectRepresentable {
public func toAnyObject() -> AnyObject {
let value = self as NSDictionary
return value
}
public static func fromAnyObject(value: AnyObject) -> Dictionary? {
let convertedValue = value as? Dictionary
return convertedValue
}
}
方法实现的第一行给出了以下错误:
&#39;字典&#39;不能转换为&NSCictionary&#39;
接下来我尝试直接扩展toAnyObject()
:
NSDictionary
Xcode在extension NSDictionary: AnyObjectRepresentable {
public func toAnyObject() -> AnyObject {
return NSDictionary(dictionary: self)
}
public static func fromAnyObject(value: AnyObject) -> NSDictionary? {
let convertedValue = value as? NSDictionary
return convertedValue
}
}
的声明中给出了以下错误:
方法&#39; fromAnyObject&#39;在非最终班级&#39; NSDictionary&#39;必须返回fromAnyObject()
以符合协议&#39; AnyObjectRepresentable&#39;
我的智慧。这可以解决吗?
谢谢,
的 大卫
更新2015-09-15 16:30
对于背景,以下是Self
的定义和实现:
SettingsStore
答案 0 :(得分:0)
如果您将 AnyObject 替换为 Any ,我想您会得到您正在寻找的结果。具体来说,替换这一行:
public class Setting<T: AnyObject>: Settable {
这一行
public class Setting<T: Any>: Settable {