gpt4 book ai didi

swift - Swift 2 中的通用设置类

转载 作者:搜寻专家 更新时间:2023-11-01 05:39:20 25 4
gpt4 key购买 nike

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

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

我有一个适用于 AnyObject 的解决方案,它由一个通用协议(protocol) (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)
}

问题在于它不适用于值类型,例如 StringBoolInt DoubleArrayDictionary 因为它们都是值类型,而值类型不符合 AnyObject 协议(protocol)。

我已经使用基于 NSStringNSNumber 的协议(protocol)和扩展解决了其中一些问题,但是 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 方法:

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

Xcode 在 toAnyObject() 方法实现的第一行给我以下错误:

'Dictionary' 不能转换为 'NSDictionary'

接下来我尝试直接扩展 NSDictionary:

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

Xcode 在声明 fromAnyObject() 时给我以下错误:

非最终类“NSDictionary”中的方法“fromAnyObject”必须返回 Self 以符合协议(protocol)“AnyObjectRepresentable”

我脑洞大开。这可以解决吗?

谢谢,
大卫

更新于 2015-09-15 16:30

作为背景,这里是SettingsStore的定义和实现:

public protocol SettingsStore {
func objectForKey(key: String) -> AnyObject?
func setObject(value: AnyObject?, forKey key: String)
func dictionaryForKey(key: String) -> [String:AnyObject]?
}
public class UserDefaultsSettingsStore {
private let userDefaults: NSUserDefaults
public init() {
self.userDefaults = NSUserDefaults.standardUserDefaults()
}
public init(suiteName: String) {
self.userDefaults = NSUserDefaults(suiteName: suiteName)!
}
}
extension UserDefaultsSettingsStore: SettingsStore {
public func objectForKey(key: String) -> AnyObject? {
return self.userDefaults.objectForKey(key)
}
public func setObject(value: AnyObject?, forKey key: String) {
self.userDefaults.setObject(value, forKey: key)
self.userDefaults.synchronize()
}
public func dictionaryForKey(key: String) -> [String : AnyObject]? {
return self.userDefaults.dictionaryForKey(key)
}
}

最佳答案

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

public class Setting<T: AnyObject>: Settable {

用这条线

public class Setting<T: Any>: Settable {

关于swift - Swift 2 中的通用设置类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32596658/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com