Why isn't the Codable init being called instead of the other required init?

自闭症网瘾萝莉.ら 提交于 2020-01-05 06:46:30

问题


I am building a game using SpriteKit and Swift 4, with a number of custom classes in the SKNode family. I am trying to use the Codable protocol with them to (hypothetically) make saving the game easier. As a bit of context, here is a high level overview of the main classes in the game:

Hero class, custom SKSpriteNode, implements Codable. The Hero class, as a property, has a dictionary in the form of: [String:MapNode]

MapNode class, custom SKSpriteNode, implements Codable. The MapNode class, as a property, has an array of TileNodes like: [TileNode]

TileNode class, custom SKSpriteNode, implements codable. The TileNode class has only primitive properties.

I seem to be able to encode everything okay, and save everything to defaults, but when I go to decode a saved game, I get the following error within the MapNode class:

Thread 1: Fatal error: init(coder:) has not been implemented

On this required init:

required init?(coder aDecoder: NSCoder) {
    // subclass of SKNode must implement this method
    fatalError("init(coder:) has not been implemented")
}

What I do not understand is why this init is even being called at all (or why it is required) because as I understand it, it is not used by the Codable protocol at all. In the class where this required init lives (MapNode), I also have the following Codable functions:

enum CodingKeys: String, CodingKey {

    case height
    case width
    case tileArray
}

required init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)

    height = try values.decode(Int.self, forKey: .height)
    width = try values.decode(Int.self, forKey: .width)

    let tileArrayData = try values.decode(Data.self, forKey: .tileArray)
    tileArray = (NSKeyedUnarchiver.unarchiveObject(with: tileArrayData) as? [TileNode])!

    self.isUserInteractionEnabled = true
    self.size = CGSize(width: width, height: height)
    self.name = "map"
    zPosition = 5

    addMapImageLayer(forMap: self)
}



func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)

    try container.encode(height, forKey: .height)
    try container.encode(width, forKey: .width)

    let tileArrayData = NSKeyedArchiver.archivedData(withRootObject: tileArray)
    try container.encode(tileArrayData, forKey: .tileArray)

}

My thought was that since I am implementing Codable on everything that the code would use the Codable functions when it needed to initialize and decode Codable encoded data. What should I be doing differently?

来源:https://stackoverflow.com/questions/50916375/why-isnt-the-codable-init-being-called-instead-of-the-other-required-init

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!