swift - 使用 "Codable"设置属性值不能通过继承工作

标签 swift codable

我无法在子类中设置 b 属性。它是继承自 Codable 的父类,并且看起来运行良好。

我觉得我错过了一些非常明显的东西,但我很难只见树木不见森林。

下面是我的问题的 Playground 示例。 b 保持为 0,尽管被设置为 10。传入的是子类,但是可以设置父属性(很奇怪!)。

class Primary : Codable {
    var a: Int = 0
}

class Secondary : Primary {
    var b: Int = 0
}

let c = Secondary.self

func testRef<T: Codable>(_ t: T.Type) {
    let json = "{\"a\":5, \"b\" : 10}".data(using: .ascii)!
    let testCodable = try? JSONDecoder().decode(t.self, from: json)
    print("a >> \((testCodable as! Primary).a)")
    print("b >> \((testCodable as! Secondary).b)")
}

testRef(c)

输出结果是:

a >> 5
b >> 0

如有任何提示或指点,我们将不胜感激。

  • 在 Xcode 9.3、Swift 4.1 中试过

最佳答案

Codable 的魔力依赖于简单性(使用不支持继承的结构)。

自定义越多,代码越多

你必须在子类中写一个自定义的初始化器来考虑继承(感谢Hamish的注释,CodingKeys和初始化器是在基类中合成的),我省略了Encodable 有意部分

class Primary : Decodable {
    var a: Int

/*
   private enum CodingKeys: String, CodingKey { case a }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        a = try container.decode(Int.self, forKey: .a)
    }
*/
}

class Secondary : Primary {
    var b: Int

    private enum CodingKeys: String, CodingKey { case b }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        b = try container.decode(Int.self, forKey: .b)
        try super.init(from: decoder)
    }
}


func testRef<T: Decodable>() throws -> T {
    let json = "{\"a\":5, \"b\" : 10}".data(using: .utf8)!
    return try JSONDecoder().decode(T.self, from: json)
}

do {
    let secondary : Secondary = try testRef()
    print(secondary.a, secondary.b) // 5 10
} catch { print(error) }

关于swift - 使用 "Codable"设置属性值不能通过继承工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50091036/

相关文章:

ios - 使用 UpdateChildValue 从 Firebase 编辑

swift - Date() 在调试中显示在 swift 5/Xcode 11 中损坏了吗?

快速过滤 Realm 上的项目

ios - 将枚举数组从 Swift 桥接到 Objective-C

arrays - Swift - 表达式解析为未使用的左值

ios - 可编码的 API 请求

json - 解析时 JSON 无效\n(带引号的)字符串

json - 使用 Codable 解析嵌套的 JSON,如 ObjectMapper Swift 4

json - 你如何设计一个可以是空字符串或 int 的可编码 JSON 字段

ios - 从泛型类型转换为特定类型