从 JSON 解码后访问对象属性时崩溃
Posted
技术标签:
【中文标题】从 JSON 解码后访问对象属性时崩溃【英文标题】:Crash when accessing Object properties after decoding from JSON 【发布时间】:2018-06-23 19:31:36 【问题描述】:我已将 JSON 值解码为对象。该对象看起来像预期的那样,但是当我尝试访问它的属性时。
let jsonData = try JSONSerialization.data(withJSONObject: JSON, options: [])
let decoder = JSONDecoder()
let doctor = try! decoder.decode(Doctor.self, from: jsonData)
let txt = "\(doctor.title). \(doctor.firstName) \(doctor.lastName)" // Runtime crash: (Thread 1: EXC_BAD_ACCESS (code=1, address=0x40))
运行时崩溃:(线程 1:EXC_BAD_ACCESS(代码=1,地址=0x40))
班级人员:
import UIKit
class Person: Codable
let firstName: String
let lastName: String
let imageURL: URL
private enum CodingKeys: String, CodingKey
case firstName
case lastName
case imageURL = "profileImgPath"
init(firstName: String, lastName: String, imageURL:URL)
self.firstName = firstName
self.lastName = lastName
self.imageURL = imageURL
班主任:
import UIKit
class Doctor: Person
var title: String
private enum CodingKeys: String, CodingKey
case title
init(firstName: String, lastName: String, imageURL:URL, title: String)
self.title = title
super.init(firstName: firstName, lastName: lastName, imageURL: imageURL)
required init(from decoder: Decoder) throws
let values = try decoder.container(keyedBy: CodingKeys.self)
self.title = try values.decode(String.self, forKey: .title)
try super.init(from: decoder)
【问题讨论】:
是firstName
和lastName
在Doctor
中的计算属性吗?你能显示Doctor
类吗?
我猜如果您不使用try!
并实际捕获异常,您可能会获得更多详细信息,您是否在Doctor 上实现了Codable
?
Doctor
是Person
的子类吗?
@Kamran 我已经更新了问题
我认为它需要在 Person 类中使用 init(from decoder:)
方法。编辑:我看到卡姆兰在他们的回答中做到了。
【参考方案1】:
当我尝试你的代码时,它产生了同样的错误,经过调查,我发现这是Swift 4.1
中的一个问题。您可以在下面查看,
https://bugs.swift.org/browse/SR-7090
目前可能的解决方案可能是如下所示的轻微重新排列,
从基类中删除Codable
一致性,即Person
,但您仍然可以通过将init
方法与docoder
一起从子类中调用来解码基类成员。子类现在将符合Codable
。
class Person
let firstName: String
let lastName: String
let imageURL: URL
private enum CodingKeys: String, CodingKey
case firstName
case lastName
case imageURL = "profileImgPath"
init(firstName: String, lastName: String, imageURL:URL)
self.firstName = firstName
self.lastName = lastName
self.imageURL = imageURL
init(from decoder: Decoder) throws
let values = try decoder.container(keyedBy: CodingKeys.self)
self.firstName = try values.decode(String.self, forKey: .firstName)
self.lastName = try values.decode(String.self, forKey: .lastName)
self.imageURL = try values.decode(URL.self, forKey: .imageURL)
class Doctor: Person, Codable
var title: String
private enum CodingKeys: String, CodingKey
case title
init(firstName: String, lastName: String, imageURL:URL, title: String)
self.title = title
super.init(firstName: firstName, lastName: lastName, imageURL: imageURL)
required override init(from decoder: Decoder) throws
let values = try decoder.container(keyedBy: CodingKeys.self)
self.title = try values.decode(String.self, forKey: .title)
try super.init(from: decoder)
现在,如果您有以下 json,它将按预期工作。
let json = """
"title":"SomeTitle",
"firstName": "SomeFirstName",
"lastName": "SomeLastName",
"profileImgPath": "urlPath"
""".data(using: .utf8)!
let decoder = JSONDecoder()
let doctor = try! decoder.decode(Doctor.self, from: json)
print(doctor.firstName)
print(doctor.lastName)
print(doctor.title)
【讨论】:
很高兴它有帮助。 基类没有来自解码器的初始化。编译器应该已经捕捉到并尖叫我承认......但这也是合乎逻辑的......以上是关于从 JSON 解码后访问对象属性时崩溃的主要内容,如果未能解决你的问题,请参考以下文章
核心数据:访问 NSManagedObject 属性时应用程序崩溃
如何使用 Alamofire 和 Swift Decode 从 JSON 解码和访问 Double
在 migratePersistentStore: 到 OS X 10.9 Mavericks 上的另一个 URL 后访问 NSManagedObject 属性时崩溃