【问题标题】:Swift 4 Codable & genericsSwift 4 可编码和泛型
【发布时间】:2017-10-12 13:47:31
【问题描述】:

我正在使用 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 接受通用值?

【问题讨论】:

  • 能否请您也添加调用函数modelForKey&lt;T&gt; 的代码?谢谢;)

标签: swift generics swift4 codable


【解决方案1】:

由于 Codable 无法在扩展中实现(还没有?),而且 SimpleModel 是 PINCache 内部的,因此您无法使其符合 Codable。

如果可能的话,我建议切换到具有支持 Codable 的协议的缓存库,例如 Cache

【讨论】:

    【解决方案2】:

    尝试func modelForKey&lt;T : SimpleModel, Decodable&gt; ... 要求将该类型限制为可解码。

    【讨论】:

      【解决方案3】:

      更改此行以检查它是否符合Decodable

      guard let cacheKey = ... as? Data, T.self is Decodable else {
      

      【讨论】:

      • 我的代码有什么不同?我已经在检查 T.self 是否为 Decodable
      • @Morniak 你在哪里检查?
      • 我的后卫的最后一条指令(第 2 行)
      • @Morniak 在您包含的代码中,您正在检查Codable 而不是Decodable
      • 哦对了!但是 Codable 意味着 Decodale。无论如何,我尝试了 Decodable 并且遇到了同样的问题。检查类型不会更改范围内变量的类型。并且 Codable 系统需要真正的类型,所以我不能将我的 var 转换为 Codable。
      【解决方案4】:

      IMO 问题不在于 PINCache。

      T.self is Codable 不会告诉编译器更多关于 T 类型的信息,因此 decoder.decode(T.self, from: data) 不会通过类型检查,即使 TDecodable

      我认为在这里分叉 RocketData 将是最简单的解决方案(如果您想继续使用 RocketData + Decodable 并且您的所有模型都符合 Decodable)。使SimpleModel符合Decodable

      【讨论】:

        【解决方案5】:
        1. 尝试创建CustomProtocol: Codable, SimpleModel

        2. 如果第1点不起作用,请尝试创建自定义类CustomClass: SimpleModel, Codable并使用modelForKey&lt;T : CustomClass&gt;

        【讨论】:

          猜你喜欢
          • 2018-10-05
          • 1970-01-01
          • 1970-01-01
          • 2018-02-06
          • 1970-01-01
          • 2021-04-21
          • 2018-02-28
          • 1970-01-01
          • 2022-07-14
          相关资源
          最近更新 更多