我試圖在Swift 2中實現一個類,該類只使用NSUserDefaults
下的任何類型的單個設置。Swift 2中的通用設置類
問題:如何定義一個類來存儲和檢索任何類型的對象,包括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
,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
方法:
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()
法實施的第一線以下錯誤:
「詞典」是無法轉換爲「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()
聲明以下錯誤:在非final類「的NSDictionary」必須返回Self
法「fromAnyObject」,以符合協議「AnyObjectRepresentable」
我在我的鬥智鬥勇。這是可以解決的嗎?
感謝,
大衛
已更新2015年9月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,關於使用任何什麼? –
關於你的錯誤,看看[協議樂趣返回自我](http://stackoverflow.com/questions/25645090/protocol-func-returning-self)。 – ABakerSmith
我曾經看過那篇文章 - Rob Napier在這個主題上寫得非常好,但不幸的是在這種情況下它並沒有幫助我。 –