提问人:Morniak 提问时间:10/12/2017 最后编辑:Paulo MattosMorniak 更新时间:11/28/2017 访问量:4412
Swift 4 Codable 和泛型
Swift 4 Codable & generics
问:
我正在使用 PINCache 向我的应用程序添加缓存,并且我处于缓存系统调用用于编码/解码的委托方法的情况。
这些方法是泛型的,但泛型值不明确符合 。因为他们是委托人,所以我无法更改签名以使泛型类型符合 .Codable
Codable
func modelForKey<T : SimpleModel>(_ cacheKey: String?, context: Any?, completion: @escaping (T?, NSError?) -> ()) {
guard let cacheKey = cacheKey, let data = cache.object(forKey: cacheKey) as? Data, T.self is Codable else {
completion(nil, nil)
return
}
let decoder = JSONDecoder()
do {
let model: T = try decoder.decode(T.self, from: data)
completion(model, nil)
} catch {
completion(nil, nil)
}
}
使用此代码,我遇到以下错误:
在参数类型中,不符合预期类型
T.Type
T
Decodable
如何强制接受通用值?decoder
答:
更改此行以检查它是否符合:Decodable
guard let cacheKey = ... as? Data, T.self is Decodable else {
评论
T.self
Decodable
Codable
Decodable
由于 Codable 还不能在扩展中实现,并且 SimpleModel 是 PINCache 的内部版本,因此无法使其符合 Codable。
如果可能的话,我建议切换到具有支持 Codable 的协议的缓存库,例如 Cache
尝试要求将该类型限制为 Decodable。func modelForKey<T : SimpleModel, Decodable> ...
IMO 问题不在于 PINCache。
T.self is Codable
不会告诉编译器有关类型的更多信息,因此不会通过类型检查,即使是 .T
decoder.decode(T.self, from: data)
T
Decodable
我认为分叉 RocketData 将是这里最简单的解决方案(如果您想继续使用 RocketData + 并且您的所有模型都符合)。使符合 。Decodable
Decodable
SimpleModel
Decodable
尝试创建
CustomProtocol: Codable, SimpleModel
如果第 1 点不起作用,请尝试创建自定义类并使用
CustomClass: SimpleModel, Codable
modelForKey<T : CustomClass>
评论
modelForKey<T>