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

时间:2018-06-23 19:31:37

标签: ios swift nsjsonserialization

我已经将JSON值解码为对象。该对象看起来像预期的一样,但是当我尝试访问它的属性时。

enter image description here

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

}

1 个答案:

答案 0 :(得分:2)

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

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

目前可能的解决方案可能是重新安排如下,

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

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,它将按预期运行。

#include<iostream>
#include<cmath>
#include<fstream>
#include<string>
#include<sstream>
 int main()
{
std::ifstream f("honey.txt");
std::string line;
while(std::getline(f,line))
{
float serial;
std::string Energy,Energy2;
std::string mu;
std::string mubar;
std::string e;
std::string ebar;
std::istringstream ss(line);
ss>>serial>>Energy>>Energy2>>mu>>mubar>>e>>ebar;
std::cout<<Energy<<"\t"<<mu<<"\n";
}
}