如何解决GameData解码后仅显示类名、无法查看属性值的问题?
解决JSON解码与对象属性查看问题
一、先解决解码阶段的类型错误
你最初碰到的Cannot convert value of type 'GameData' to expected argument type 'Data'错误,核心问题是传入decode方法的data并非Data类型——它是Any?类型。你后续做的类型转换思路是对的,但别用强制解包!,这会在转换失败时直接崩溃,建议换成更安全的可选绑定写法:
if let data = data as? Data { let decoder = JSONDecoder() do { let dataTest = try decoder.decode(GameData.self, from: data) // 这里处理解码成功后的GameData对象 } catch { print("解码失败:\(error)") } } else { print("无法将响应数据转换为Data类型") }
另外补充一句:你的GameData类不需要额外写init()方法——Codable协议会自动生成默认初始化器,只要所有属性都符合Codable要求(你的Bool、String、[[Int]]都满足)。
二、为什么打印看不到属性值?
你看到data: Optional(projectName.GameData),是因为Swift中类默认的字符串描述只显示类型名称,不会自动遍历打印所有属性。要查看具体属性值,有几种简单方法:
- 直接打印单个属性
如果只需要查看部分属性,可以直接针对性打印:
print("玩家1是否回合:\(dataTest?.isPlayerOneTurn ?? false)") print("棋盘数据:\(dataTest?.board ?? [])")
- 让
GameData遵守CustomStringConvertible协议
手动实现description属性,自定义打印的内容格式:
class GameData : Codable, CustomStringConvertible { var isPlayerOneTurn: Bool! var wasCreated: Bool! var playerOne: String! var playerTwo: String! var board: [[Int]]! init() { } var description: String { return """ GameData详情: - 玩家1回合:\(isPlayerOneTurn) - 是否已创建:\(wasCreated) - 玩家1昵称:\(playerOne ?? "未设置") - 玩家2昵称:\(playerTwo ?? "未设置") - 棋盘布局:\(board ?? []) """ } }
之后直接打印dataTest就能看到完整的属性信息了。
- 使用Swift内置的
dump()方法dump()会递归打印对象的所有层级属性和值,不需要修改GameData类:
dump(dataTest)
输出会类似:
▿ Optional(projectName.GameData) ▿ some : projectName.GameData - isPlayerOneTurn: true - wasCreated: true - playerOne: "Alice" - playerTwo: "Bob" ▿ board: 3 elements ▿ 0 : 3 elements - 0: 1 - 1: 0 - 2: 2 ▿ 1 : 3 elements - 0: 0 - 1: 1 - 2: 0 ▿ 2 : 3 elements - 0: 2 - 1: 0 - 2: 1
最后提个小建议:尽量避免用隐式解包可选类型(!),换成普通可选类型(?)能减少空值崩溃的风险。
内容的提问来源于stack exchange,提问作者Joshua
相关产品推荐
相关产品推荐

