2016-06-13 84 views
-1

我想在NSUserDefaults中存储通用数组,但出现以下错误:Cannot convert value of type 'Array<T>' to expected argument type 'AnyObject?'将通用数组存储在NSUserDefaults中

我该如何解决这个问题?

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

您应该将T定义为NSCoding符合类。所以当你要存储数组时,你将要存储一个NSKeyedArchiver.archiveDataWithRootObject()结果数组。然后,在loadSet方法返回一个Set<T>,你应该unarchive所有对象:

let storedData = NSUserDefaults.standardUserDefaults. ... 
return storedData.flatMap { return NSKeyedUnarchiver.unarchiveObjectWithData($0) } 
+0

但是,如果我有一个'设置'这不会是例如'设置'兼容。 – multiholle

+0

因此,尝试接受每个“T”并尝试检查方法中的“T”类型 –

1

像@lucasD说,T需要顺应NSCoding ATLEAST。所以代码看起来像这样。

 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的情况下,不能正确地推断,因为我们不能从外部指定它,据我所知。我会首先尝试返回NSObject或Set<AnyObject> or Set<NSCoding>,然后键入明确。让我知道如果这是更好的方式。

你可以看看这个SO帖子,以获得更多关于泛型参数为什么不能从外部专门化的更多信息。 SO Generics specialization

相关问题