JSONEncoder.encode 产生 : Thread 1: EXC_BAD_ACCESS in case of inheritance

标签 json swift xcode encoding

为了与我的服务器通信,我使用了 NetworkMessages 的对象:

class NetworkMessage: Codable {

    var version:Int?;

    required init() {

    }

}


class AddPlayerRequest: NetworkMessage {

    var playerName: String?;
    var playerHashedPw:String?;


}

我现在正尝试将我的对象编码为字符串,以便通过网络将其发送到我的服务器:

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(netMsg)
let stringToSend = String(data: data, encoding: .utf8)
/* and send the string to the Server here... */

现在,当我尝试发送类型为 NetworkMessage 的对象时,一切正常,但是当我使用 NetworkMessage 的子类时,在本例中为 CreatePlayerRequest ,会抛出这个错误:

Thread 1: EXC_BAD_ACCESS (code=1, address=0x10)

在这一行:

let data = try! encoder.encode(netMsg)

感谢您的帮助!

******* 更新 *******

我现在复制了你的代码并在另一行中得到了错误(见评论):

do {
        let netMsg = AddPlayerRequest()
        netMsg.playerName = "Test"
        netMsg.playerHashedPw = "hynt87t7t76yt=="


        let encoder = JSONEncoder()
        encoder.outputFormatting = .prettyPrinted
        let data = try encoder.encode(netMsg) /* Thread 1: EXC_BAD_ACCESS */
        let stringToSend = String(data: data, encoding: .utf8)

        print(stringToSend ?? "")
    } catch {
        print(error)
}

最佳答案

在继承的情况下,您必须自己实现编码。所以你需要指定CodingKeys并实现init(from:)encode(to:)

There is a bug report .

所以你可以像这样改变你的类,它会起作用:

class NetworkMessage: Codable {
    var version:Int?
}


class AddPlayerRequest: NetworkMessage {

    var playerName: String?
    var playerHashedPw:String?

    private enum CodingKeys: String, CodingKey { case playerName; case playerHashedPw }

    override func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(playerName, forKey: .playerName)
        try container.encode(playerHashedPw, forKey: .playerHashedPw)

        try super.encode(to: encoder)
    }
}

测试代码:

let netMsg = AddPlayerRequest()
netMsg.playerName = "Test"
netMsg.playerHashedPw = "hynt87t7t76yt=="
netMsg.version = 1

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
do {
    let data = try encoder.encode(netMsg)
    let stringToSend = String(data: data, encoding: .utf8)

    print(stringToSend ?? "")
} catch {
    print(error)
}

这是输出:

{
  "version" : 1,
  "playerHashedPw" : "hynt87t7t76yt==",
  "playerName" : "Test"
}

关于JSONEncoder.encode 产生 : Thread 1: EXC_BAD_ACCESS in case of inheritance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50320976/

相关文章:

ios - 错误: Expected identifier or '(' after usage of old Objective C library in Swift project through bridging header

java - 如何用java程序制作层次结构的Json结构

java - 使用 Java 或 JSON 进行拆分

javascript - 映射 JSON 条目以选择选项

ios - 无法执行存储在 Array[Any] 中的对象的方法

swift - iMessage 应用 Xcode

javascript - 如何使用 Lodash/JavaScript 重新格式化此 JSON?

arrays - 如何从数组<>中删除协议(protocol)

arrays - Json 到数组与数组到字典

iphone - OpenFeint 与 GameCenter 真的那么容易吗?