Swift: декодировать данные в объект, который является унаследованным классом, приходит ошибка - PullRequest
0 голосов
/ 28 июня 2018

Я работаю над декодированием данных в объект. Модельные классы:


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 голосов
/ 28 июня 2018

Это проблема в Swift 4.1.

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

Вы можете исправить это сейчас, удалив Codable соответствие с базы class. И как только проблема будет исправлена ​​в следующей версии Xcode/Swift, вы можете вернуться обратно.

Вот как вы можете достичь этого с минимальными усилиями, чтобы вернуться в будущее, переместив Codable в базу class. Вы также можете попробовать в бета-версии Xcode 10, где ваш текущий код может работать как положено.

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
...