我正在尝试在NSUserDefaults中存储一个通用数组,但是我收到以下错误:Cannot convert value of type 'Array<T>' to expected argument type 'AnyObject?'
。
我该如何解决这个问题?
public class PropertyStore {
private let userDefaults = NSUserDefaults.standardUserDefaults()
public func loadSet<T>(key: String) -> Set<T>? {
guard let array = userDefaults.objectForKey(key) as? [T] else {
return nil
}
return Set<T>(array)
}
public func saveSet<T>(key: String, value: Set<T>) {
let array = Array(value)
userDefaults.setObject(array, forKey: key) // <- ERROR
}
}
答案 0 :(得分:1)
就像@lucasD所说,T需要至少符合NSCoding。所以代码看起来像这样。
public func saveSet<T: NSCoding>(key: String, value: Set<T>) {
let array = Array(value)
userDefaults.setObject(array, forKey: key)
}
然而,由于以下原因,这不起作用:
public func loadSet<T: NSCoding>(key: String) -> Set<T>? {
guard let array = userDefaults.objectForKey(key) as? [T] else {
return nil
}
return Set<T>(array)
}
let defaults = PropertyStore()
defaults.saveSet("array", value: [1,2,3])
///defaults.loadSet<Int>("array") ===> Cannot explicitly specialize a function
///defaults.loadSet("array") ===> Cannot infer Type T
//let a: Set<Int>? = defaults.loadSet("array") ==> T cannot be inferred
在loadSet
类型T的情况下,无法正确推断T,因为据我所知,我们无法从外部指定它。我首先尝试返回NSObject或Set<AnyObject> or Set<NSCoding>
,然后显式输入。如果有更好的方法让我知道。
您可以查看此SO帖子,了解更多有关泛型参数无法从外部进行专业化的原因。 SO Generics specialization
答案 1 :(得分:0)
您应该将T
定义为NSCoding
符合级别。因此,当您要存储数组时,您将存储一组NSKeyedArchiver.archiveDataWithRootObject()
个结果。然后,要在Set<T>
方法中返回loadSet
,您应该unarchive
所有对象:
let storedData = NSUserDefaults.standardUserDefaults. ...
return storedData.flatMap { return NSKeyedUnarchiver.unarchiveObjectWithData($0) }