0

我想在我的 Swift 应用程序中编码和解码一些对象。我有以下 2 节课。

enum TileSize : Int, Codable
{
    case smallTile = 3
    case mediumTile = 2
    case largeTile = 1
}

class Tile: NSObject, Codable
{
    var tileSize: TileSize = .smallTile
    var imageName: String = "";
    var isDragged = false

    private enum CodingKeys : String, CodingKey
    {
        case tileSize
        case imageName
    }
}

class ConsumptionTile: Tile
{
    override var imageName: String
    {
        get
        {
            return "consumption"
        }
        set
        {
            super.imageName = newValue
        }
    }
}

这是代码,我如何尝试对对象进行编码。

    var defaultTiles : [Tile] = []
    defaultTiles.append(ConsumptionTile(tileSize: .largeTile))
    defaultTiles.append(Tile(tileSize: .largeTile, imageName: "my-devices"))
    defaultTiles.append(Tile(tileSize: .mediumTile, imageName: "live-verbrauch"))
    defaultTiles.append(Tile(tileSize: .smallTile, imageName: "zaehlerstand"))
    defaultTiles.append(Tile(tileSize: .smallTile, imageName: "vertrag"))

    let jsonEncoder = JSONEncoder()
    let jsonData = try jsonEncoder.encode(defaultTiles)

我认为问题在于,我尝试对子类 ConsumptionTile 的对象进行编码,但数组的类型为 [Tile]。但我不知道如何解决这个问题。我必须将所有 Tile 类编码为一个数据对象。以后会有更多的子类,而不仅仅是 ConsumptionTile。

我在运行时遇到的错误只是 try jsonEncoder.encode(defaultTiles) 行上的一个断点,带有消息 Thread 1: EXC_BAD_ACCESS (code=1, address=0x8)

我希望有人能帮帮忙。谢谢!

4

1 回答 1

0

我只是在操场上尝试过,但无法重现该错误。唯一的潜在问题是通过encode-decode过程丢失类型信息,其中ConsumptionTile被解码为Tile.

如果你把它放到操场上并尝试运行它,你会看到自己。

import Foundation

enum TileSize : Int, Codable
{
    case smallTile = 3
    case mediumTile = 2
    case largeTile = 1
}

class Tile: NSObject, Codable
{
    var tileSize: TileSize = .smallTile
    var imageName: String = "";
    var isDragged = false

    init(tileSize: TileSize, imageName: String) {
        self.tileSize = tileSize
        self.imageName = imageName
    }

    private enum CodingKeys : String, CodingKey
    {
        case tileSize
        case imageName
    }
}

class ConsumptionTile: Tile
{
    init(tileSize: TileSize) {
        super.init(tileSize: tileSize, imageName: "")
    }

    required init(from decoder: Decoder) throws {
        fatalError("init(from:) has not been implemented")
    }

    override var imageName: String
        {
        get
        {
            return "consumption"
        }
        set
        {
            super.imageName = newValue
        }
    }
}

var defaultTiles : [Tile] = []
defaultTiles.append(ConsumptionTile(tileSize: .largeTile))
defaultTiles.append(Tile(tileSize: .largeTile, imageName: "my-devices"))
defaultTiles.append(Tile(tileSize: .mediumTile, imageName: "live-verbrauch"))
defaultTiles.append(Tile(tileSize: .smallTile, imageName: "zaehlerstand"))
defaultTiles.append(Tile(tileSize: .smallTile, imageName: "vertrag"))

let jsonEncoder = JSONEncoder()
let jsonData = try! jsonEncoder.encode(defaultTiles)

let out = try! JSONDecoder().decode([Tile].self, from: jsonData)
for tile in out {
    print(">>> \(tile.imageName)")
}
于 2017-09-24T10:51:30.947 回答