当我解码一个子类(RegularCard)的数组时,我得到一个超类(Card)的数组。编码很好,我测试了它并且编码工作正常。但是,当我解码时,不会调用解码子类(RegularCard)的函数。我的代码如下。我在另一篇文章中发现了以下错误:
2017 年 6 月 25 日更新:我最终向 Apple 提交了一个关于此的错误。rdar://32911973 - 不幸的是,包含子类的超类数组的编码/解码循环:超类元素将导致数组中的所有元素都被解码为超类(永远不会调用子类的 init(from:),从而导致数据丢失或更糟)。
这是在这篇文章中。
class Card : Codable {
var id: Int
var front: String
var score: Int
var cardType : CardType
init(id: Int, front : String, score: Int, cardType : CardType) {
self.id = id
self.front = front
self.score = score
self.cardType = cardType
}
enum CodingKeys : String, CodingKey {
case id
case front
case score
case cardType
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
print("encoding super")
try container.encode(id, forKey: .id)
try container.encode(front, forKey: .front)
try container.encode(score, forKey: .score)
try container.encode(cardType.rawValue, forKey: .cardType)
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
print("decoding super")
self.id = try values.decode(Int.self, forKey: .id)
self.front = try values.decode(String.self, forKey: .front)
self.score = try values.decode(Int.self, forKey: .score)
self.cardType = CardType(rawValue: try values.decode(String.self, forKey: .cardType))!
}
}
enum CardType : String {
case regular = "regular"
case multipleChoice = "multipleChoice"
case numbered = "numbered"
case bulleted = "bulleted"
case acronym = "acronym"
case image = "image"
}
class RegularCard : Card {
var back: String
init(id: Int, front : String, score: Int, back : String) {
self.back = back
super.init(id: id, front: front, score: score, cardType: .regular)
}
enum CodingKeys : String, CodingKey {
case back
case id
case front
case score
case cardType
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
print("encoding Regular")
try super.encode(to: encoder)
try container.encode(back, forKey: .back)
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
print("decoding regular")
back = try values.decode(String.self, forKey: .back)
try super.init(from: decoder)
}
}
'''