2017-09-24 30 views
0

我想編碼和解碼我的Swift應用程序中的一些對象。我有以下2個班。Swift:JSONEcoder EXC_BAD_ACCESS

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。

我得到的運行時錯誤只是在嘗試jsonEncoder.encode(defaultTiles)與消息線程1線斷點:EXC_BAD_ACCESS(代碼= 1,地址= 0x8中)

我希望有人可以提供幫助。謝謝!

回答

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)") 
} 
+0

你說得對。它在遊樂場中工作,我弄明白了,如果Tile和ConsumptionTile子類在同一個文件中,它可以在我的應用程序中運行。如果它們位於不同的文件中,則會再次出現BAD_ACCESS錯誤。 必須有一個方法是(文件)私有的,並且由類自動實現(如默認的init)。我試圖找出它... – Fabian

+0

嗯,有趣..我會看看它 –

+2

我不確定,如果它真的是問題,但我實現了編碼(到:編碼器)函數的可編程協議,它的工作。 – Fabian