从JSON解码后访问Object属性时崩溃

我已将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))

class级人员:

 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 } } 

class主任:

 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) } } 

当我尝试你的代码时,它产生了同样的错误,经过调查,我发现这是Swift 4.1一个问题。 你可以在下面查看,

https://bugs.swift.org/browse/SR-7090

现在可能的解决方案可能是如下所示的轻微重新排列,

从基类(即Person删除Codable一致性,但您仍然可以通过保持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)