Swift 2中的通用设置类

时间:2015-09-15 22:21:26

标签: swift dictionary swift2

我试图在Swift 2中为一个使用NSUserDefaults的任何类型的设置实现一个类。

问题:如何定义用于存储和检索任何类型对象的类,包括Dictionary

我有一个适用于AnyObject的解决方案,它由通用协议(Settable)和通用类(Setting)组成。 SettingsStoreNSUserDefaults的包装。

// 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)
}

问题在于它无法使用值类型,例如StringBoolIntDouble,{{1} }或Array因为它们都是值类型,而且值类型不符合Dictionary协议。

我已经使用基于AnyObjectNSString的协议和扩展解决了其中一些问题,但解决方案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

1 个答案:

答案 0 :(得分:0)

如果您将 AnyObject 替换为 Any ,我想您会得到您正在寻找的结果。具体来说,替换这一行:

public class Setting<T: AnyObject>: Settable {

这一行

public class Setting<T: Any>: Settable {