我有最奇怪的问题。执行JSON序列化并创建对象后,尝试访问子类的任何属性时代码会崩溃。当我尝试访问对象超类的属性时,它们将被正确打印。
这是课程:
import UIKit
class Patient: Person {
var approved: Bool
var doctorId: Int
private enum CodingKeys: String, CodingKey {
case approved
case doctorId
}
init(id: String, name: String, lastName: String, phoneNumber: String, email: String, imageURL:URL, approved:Bool, doctorId:Int) {
self.approved = approved
self.doctorId = doctorId
super.init(id: id, firstName: name, lastName: lastName, imageURL: imageURL)
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
self.approved = try values.decode(Bool.self, forKey: .approved)
self.doctorId = try values.decode(Int.self, forKey: .doctorId)
try super.init(from: decoder)
}
var description: String {
return "\(type(of: self)) - (\(self.firstName), \(self.lastName))" //superclass properties
}
}
struct PatientsList : Codable {
let patients: [Patient]
}
人员班:
class Person: Codable {
let firstName: String
let lastName: String
let imageURL: URL?
let id: String
private enum CodingKeys: String, CodingKey {
case firstName
case lastName
case imageURL = "profileImgPath"
case id = "_id"
}
init(id: String, firstName: String, lastName: String, imageURL:URL) {
self.id = id
self.firstName = firstName
self.lastName = lastName
self.imageURL = imageURL
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
self.id = try values.decode(String.self, forKey: .id)
self.firstName = try values.decode(String.self, forKey: .firstName)
self.lastName = try values.decode(String.self, forKey: .lastName)
self.imageURL = try values.decodeIfPresent(URL.self, forKey: .imageURL)
}
}
这是我执行序列化的方式:
do {
let jsonData = try JSONSerialization.data(withJSONObject: JSON, options: [])
let decoder = JSONDecoder()
let patientList = try! decoder.decode(PatientsList.self, from: jsonData)
completionBlock(.success(patientList.patients))
} catch {
print(error.localizedDescription)
}
这里是 //在控制台中:po(Patient.approved)打印false //在控制台中:表达式dump(患者)
▿iHeal.Patient#0▿超级:iHeal.Person
firstName: "Sarah" lastName: "Connor" imageURL: nil id: "5b367491052aaca6489e4805"
生日:“ 1980-06-10T00:00:00.000Z”
已批准:错误
doctorId:12
print(patient.approved) //crash
print(patient.doctorId) // if I comment out previous line, this one crashes
线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x200000002)
我能提到的另一件奇怪的事:患者上没有描述。
print(patient) // prints plain: <Patient: 0x608000141c30>
Json:
{
"patients": [
{
"approved": false,
"_id": "5b367491052aaca6489e4805",
"birthDate": "1980-06-10T00:00:00.000Z",
"doctorId": 12,
"firstName": "Sarah",
"lastName": "Connor"
},
{
"approved": false,
"drains": [],
"_id": "5b3674e5052aaca6489e66b3",
"__v": 0,
"birthDate": "1980-06-10T00:00:00.000Z",
"doctorId": 12,
"firstName": "Sarah",
"lastName": "Connor"
}
]
}
答案 0 :(得分:2)
重复的:Crash when accessing Object properties after decoding from JSON
从基类即Person中删除了Codable
一致性,但是您仍然可以通过保留要从子类中调用的带有docoder的init方法来解码基类成员。子类现在将符合Codable。
答案 1 :(得分:0)
我认为我也有类似的问题,实际上是nil,但是当您在控制台中打印它时,它返回false。尝试在print(patient.approved)
之前添加一个断点,然后在控制台expression patient.approved = false
中输入一个断点,看看它是否崩溃了(从该刹车点继续之后)。如果没有,那么你知道出了什么问题。
答案 2 :(得分:0)
您可以使用以下代码尝试使用if let条件来防止应用崩溃:
if let isApproved = patient.approved {
print(isApproved)
}
此代码将检查approved
属性的nil条件,它将检查属性是否为nil,然后将值分配给isApproved
参数,否则条件将消失并且代码不会在if block
内部执行。
这将是防止崩溃的更好解决方案。
答案 3 :(得分:0)
您应该发布JSON及其解析方式。
中的一个最小示例import Cocoa
let jsonData = """
{
"doctorId": 12345,
"approved": false
}
""".data(using: .utf8)!
struct Patient : Codable {
var approved: Bool
var doctorId: Int
}
do {
let patient = try JSONDecoder().decode(Patient.self, from:jsonData)
print(patient)
} catch {
print(error)
}
只要遵循JSON约定,就会为您提供布尔值的无故障解析。您必须提供以上信息,才能使答案更具体。
不幸的是,重现错误仍然不容易。我尝试过
import Cocoa
let jsonData = """
{
"patients": [
{
"approved": false,
"drains": [],
"_id": "5b367491052aaca6489e4805",
"user": {
"_id": "5b36747d28c1c608808274ce",
"email": "17@iheal.com"
},
"__v": 0,
"birthDate": "1980-06-10T00:00:00.000Z",
"doctorId": 12,
"firstName": "Sarah",
"lastName": "Connor",
"phoneNum": "123"
},
{
"approved": false,
"drains": [],
"_id": "5b3674e5052aaca6489e66b3",
"user": {
"_id": "5b3674e428c1c608808274cf",
"email": "18@iheal.com"
},
"__v": 0,
"birthDate": "1980-06-10T00:00:00.000Z",
"doctorId": 12,
"firstName": "Sarah",
"lastName": "Connor",
"phoneNum": "123"
}
]
}
""".data(using: .utf8)!
struct Patient : Codable {
var approved: Bool
var doctorId: Int
}
struct PatientList: Codable{
let patients: [Patient]
}
do {
let patients = try JSONDecoder().decode(PatientList.self, from:jsonData)
print(patients)
} catch {
print(error)
}
但是这仍然没有任何问题。据我所知,我将不得不猜测您的Person
类是什么样子,但很可能是Codable
。坦白地说,我确实有继承Codable
类型的经验,但是您的方法看起来并不合理。但是 很难判断您的Person
类是否不是问题的一部分(当前形式的JSON解析也不是)。恐怕您必须发布这些内容才能获得有意义的答复。