【发布时间】:2016-10-24 14:45:46
【问题描述】:
我正在尝试为我的应用创建一个generic 存储,其中可以存储Serializable 项目。
我有一些实现Serializable protocol的结构
protocol Serializable {
func serialize() -> [String: AnyObject]
init?(byDeserializing dictionary : [String: AnyObject])
}
这是我的Storage Protocol
protocol Storage {
func getItems<T:Serializable>(completion : @escaping ([T]?)-> Void )
func save<T:Serializable>(_ items : [T], completion : @escaping (Bool)-> Void )
}
extension Storage {
func data<T:Serializable>(from serializableItems : [T]) -> Data? {
var serializedItems = [Dictionary<String,AnyObject>]()
for item in serializableItems {
serializedItems.append(item.serialize())
}
guard let serializedData = try? PropertyListSerialization.data(fromPropertyList: serializedItems, format:.binary, options:0) else {
return nil;
}
return serializedData
}
func serializedItems(from data : Data) -> [Dictionary<String, AnyObject>]? {
guard let serilizedItems = try? PropertyListSerialization.propertyList(from: data, options: .mutableContainers, format: nil) as? [Dictionary<String,AnyObject>] else {
return nil
}
return serilizedItems
}
func deserialize<T:Serializable>(from serializedItems: [[String : AnyObject]] ) -> [T] {
var items = [T]()
for serializedItem in serializedItems {
if let item = T(byDeserializing:serializedItem){
items.append(item)
}
}
return items
}
}
当应用想要恢复存储的项目时,只需调用self.storage.getItems....
func getItems<T : Serializable>(completion: @escaping ([T]?) -> Void) {
let path = fileURL().path
concurrentQueue.async {
guard let serializedItems = NSArray(contentsOfFile: path) as? [[String : AnyObject]], serializedItems.count > 0 else {
completion(nil)
return
}
let deserializedItems = self.deserialize(from: serializedItems)
completion(deserializedItems)
}
}
我调用getItems 方法,我在两个存储协调器中都得到了这个编译错误
PlistStorageCoordinator
UserDefaultrsStorageCoordinator
在我向这个方法添加泛型之前,它工作得很好。有谁知道哪里出了问题?
我不知道为什么,但这可以解决它。我不喜欢它,因为我在两个存储中都复制了代码。谁能给我解释一下?
func getItems<T : Serializable>(completion: @escaping ([T]?) -> Void) {
concurrentQueue.async {
guard let data = self.userDefaults.data(forKey: self.modelKey), let serializedItems = self.serializedItems(from: data), serializedItems.count > 0 else {
completion(nil)
return
}
var items = [T]()
for serializedItem in serializedItems {
if let item = T(byDeserializing:serializedItem){
items.append(item)
}
}
completion(items)
}
}
【问题讨论】:
-
你是如何定义
self.storage的。从错误中我认为它不是以对象确认Serializable协议的格式。 -
尝试将类型信息添加到元素中,例如:
self.storage.getIems { (elements:[CarouselPoi]) in -
它不起作用..
Cannot convert value of type([CarouselPoi]) -> ()` 到预期的参数类型([_]?) -> Void