斯威夫特:解码数据到对象是继承类来错误

时间:2018-06-28 04:35:53

标签: swift inheritance decode decodable

我正在将数据解码为对象。模型类是:


class ZZBaseObj: Codable {
    var fid: String

    init() {
        fid = ""

    }
    private enum CodingKeys:String, CodingKey {
        case id
    }
    required init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)    
        fid = try values.decode(String.self, forKey: CodingKeys.id)

    }
}

class ZZFileObj: ZZBaseObj {
    var columns:[String]
    override init() {
        columns = [String]()
        super.init()
    }
    private enum CodingKeys:String, CodingKey {
        case columns
    }
    required init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        columns = try values.decode([String].self, forKey: CodingKeys.columns)
        try super.init(from: decoder)

    }
}

json数据如下:


(
{
    columns =     (
        "first name",
        last,
        subject,
        address,
        age
    );
    id = "1lYc8iIzMdfdfgjGYMKwO4-X3fWe-4GlzfQ-dfs";

},
{
    columns =     (
        "2018/1/30",
        100,
        "9800"
    );
    id = "1fdsafdgfQL-fdfdf-fdf";
}
)

当我尝试使用JSONDecoder()将数据解码为对象时,没有错误。我得到了resultArray,在控制台中,我可以看到元素。接下来是EXC_BAD_ACCESS,涉及以下代码:


let obj = resultArray[0]
let content = obj.columns //---------error happens here

我了解这是一个内存问题,但是当我尝试在此处以及lldb输入中设置断点时:

po obj.columns

它打印出列的内容。
这使我感到困惑。由于类ZZFileObj是从ZZBaseObj继承的,我猜想继承中缺少一些东西。我尝试制作一个包含fid和列的新类,这没有错误。但是,有一个共同的属性,因此我需要为模型提供这样的基类。
请帮忙看看。

1 个答案:

答案 0 :(得分:0)

这是Swift 4.1中的问题。

https://bugs.swift.org/browse/SR-7090

您现在可以通过从基础Codable删除class一致性来解决问题。并且,在即将发布的Xcode/Swift版本中解决了该问题之后,您可以还原。

在这里,您可以通过将Codable移至基础class,以最小的努力实现将来的还原。您还可以尝试在Xcode 10的Beta版中尝试使用当前版本的代码。

class ZZBaseObj {
    var id: String

    init() {
        id = ""

    }
    private enum CodingKeys:String, CodingKey {
        case id
    }
    required init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        id = try values.decode(String.self, forKey: CodingKeys.id)

    }
}

class ZZFileObj: ZZBaseObj, Codable {
    var columns:[String]
    override init() {
        columns = [String]()
        super.init()
    }
    private enum CodingKeys:String, CodingKey {
        case columns
    }
    required init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        columns = try values.decode([String].self, forKey: CodingKeys.columns)
        try super.init(from: decoder)

    }
}

let json = """
[
{
  "columns":["some text 1", "some text 2"],
  "id": "1lYc8iIzMdfdfgjGYMKwO4-X3fWe-4GlzfQ-dfs"
},
{
  "columns":["some text 3", "some text 4"],
  "id": "1lYc8iIzMdfdfgjGYMKwO4-X3fWe-4GlzfQ-dfs"
}
]
""".data(using: .utf8)!

let decoder = JSONDecoder()
let obj = try! decoder.decode([ZZFileObj].self, from: json)
print(obj.first!.columns)
print(obj.first!.id)

输出:

["some text 1", "some text 2"]
1lYc8iIzMdfdfgjGYMKwO4-X3fWe-4GlzfQ-dfs