Swift JSONDecoder 解码错误:错误:执行被中断,原因:EXC_BAD_ACCESS (code=1, address=0x5e48)

Posted

技术标签:

【中文标题】Swift JSONDecoder 解码错误:错误:执行被中断,原因:EXC_BAD_ACCESS (code=1, address=0x5e48)【英文标题】:Swift JSONDecoder decode error: error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x5e48) 【发布时间】:2021-05-17 19:22:56 【问题描述】:

我正在尝试在 Playground 中解码以下 JSON,并遇到 EXC_BAD_ACCESS 错误。理想情况下,我想解码 Person 结构中的所有属性,但是,我现在只能解码那些未注释的属性。一旦我取消任何评论一次,它就会抛出错误执行被中断,原因:EXC_BAD_ACCESS (code=1, address=0x5e48)。。我在这里做错了什么?我用谷歌搜索了很多,找不到任何答案。

提前感谢您的帮助!


struct Address: Decodable 
   var line1: String
   var city: String
   var region: String
   var postalCode: String
   var countryCode: String


struct CityCoordinate : Decodable 
   var latitude: Double
   var longitude: Double


struct Thumbnail: Decodable 
   var url: String
   var width: Int
   var height: Int


struct Headshot: Decodable 
   var url: String
   var width: Int
   var height: Int
   var sourceUrl: String
   var thumbnails: [Thumbnail]?


struct Meta : Decodable 
   var id: String



struct Person : Decodable 
   //var newPatients: Bool?
   var address: Address
   var description: String?
   var name: String
   var cityCoordinate: CityCoordinate
   //var baseURL: String?
//   var c_baseURL: String?
  // var headhshot: Headshot?
  // var insuranceAccepted: [String]?
   //var expertises: [String]?
  // var meta: Meta
   
   enum CodingKeys : String, CodingKey 
       //case newPatients = "acceptingNewPatients"
       case address
       case description
       case name
       case cityCoordinate
      // case headhshot
      // case insuranceAccepted
       //case baseURL = "c_baseURL"
       //case expertises = "c_expertises"
   
   
   init(from decoder: Decoder) throws 
       let container = try decoder.container(keyedBy: CodingKeys.self)
       //self.newPatients = try container.decodeIfPresent(Bool.self, forKey: .newPatients) ?? false
       self.address = try container.decode(Address.self, forKey: .address)
       self.description = try container.decode(String.self, forKey: .description)
       self.name = try container.decode(String.self, forKey: .name)
       self.cityCoordinate = try container.decode(CityCoordinate.self, forKey: .cityCoordinate)
      // self.insuranceAccepted = try? container.decodeIfPresent([String].self, forKey: .insuranceAccepted) ?? []
       //self.baseURL = try? container.decodeIfPresent(String.self, forKey: .baseURL) ?? ""
      // self.headhshot = try? container.decodeIfPresent(Headshot.self, forKey: .headhshot)
      // self.expertises = try? container.decodeIfPresent([String].self, forKey: .expertises) ?? []
   



let json2 = """

   "acceptingNewPatients": true,
   "address": 
       "line1": "111 7th Ave",
       "city": "New York",
       "region": "NY",
       "postalCode": "10005",
       "countryCode": "US"
   ,
   "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
   "name": "John Doe",
   "cityCoordinate": 
       "latitude": 41.78200149536133,
       "longitude": -72.83170318603516
   ,
   "c_baseURL": "https://some-url.dummy.com/my-profile/current",
   "headshot": 
       "url": "https://some-url.dummy.com/my-profile/current/p/ooREDemnhmfahTVexnEyXRC4GTfeKdCDWgUr-GRL11Y/199x199.png",
       "width": 199,
       "height": 199,
       "sourceUrl": "https://some-url.dummy.com/my-profile/current/p/ooREDemnhmfahTVexnEyXRC4GTfeKdCDWgUr-GRL11Y/199x199.png",
       "thumbnails": [
           "url": "https://some-url.dummy.com/my-profile/current/p/ooREDemnhmfahTVexnEyXRC4GTfeKdCDWgUr-GRL11Y/196x196.png",
           "width": 196,
           "height": 196
       ]
   ,
   "insuranceAccepted": ["Finibus", "anything", "hidden", "consectetur" ],
   "meta": 
       "accountId": "967081498762345229",
       "uid": "Nd28v0",
       "id": "5119-13270",
       "timestamp": "2021-03-24T12:10:36",
       "labels": ["61280", "61288", "84273", "117907", "122937", "126160"],
       "folderId": "351068",
       "schemaTypes": ["therefore", "popular", "commodo", "voluptatem"],
       "language": "en",
       "countryCode": "US",
       "entityType": "informationProfessional"
   


""".data(using: .utf8)!

let person = try JSONDecoder().decode(Person.self, from:json2)
print(person)

【问题讨论】:

try 行包裹在do - catch 块中,将print 包裹在error 在取消注释所有内容时(以及 meta 的缺失行)对我来说无法重现 【参考方案1】:

我认为有两三个问题导致崩溃,第一是缺少元数据,第二是没有c_expertise,最后,当Headshot?init 中是可选的时在这些更改之后,您需要使用 try 而不是 try? 来解码可选密钥:

    struct Address: Decodable 
   var line1: String
   var city: String
   var region: String
   var postalCode: String
   var countryCode: String


struct CityCoordinate : Decodable 
   var latitude: Double
   var longitude: Double


struct Thumbnail: Decodable 
   var url: String
   var width: Int
   var height: Int


struct Headshot: Decodable 
   var url: String
   var width: Int
   var height: Int
   var sourceUrl: String
   var thumbnails: [Thumbnail]?


struct Meta : Decodable 
   var id: String



struct Person : Decodable 
   var newPatients: Bool?
   var address: Address
   var description: String?
   var name: String
   var cityCoordinate: CityCoordinate
   var baseURL: String?
   var c_baseURL: String?
   var headhshot: Headshot?
   var insuranceAccepted: [String]?
   var expertises: [String]?
   var meta: Meta?
   
   enum CodingKeys : String, CodingKey 
       case newPatients = "acceptingNewPatients"
       case address
       case description
       case name
       case cityCoordinate
       case headhshot
       case insuranceAccepted
       case baseURL = "c_baseURL"
    // case expertises = "c_expertises"
       case meta
   
   
   init(from decoder: Decoder) throws 
       let container = try decoder.container(keyedBy: CodingKeys.self)
       self.newPatients = try container.decodeIfPresent(Bool.self, forKey: .newPatients) ?? false
       self.address = try container.decode(Address.self, forKey: .address)
       self.description = try container.decode(String.self, forKey: .description)
       self.name = try container.decode(String.self, forKey: .name)
       self.cityCoordinate = try container.decode(CityCoordinate.self, forKey: .cityCoordinate)
       self.insuranceAccepted = try? container.decodeIfPresent([String].self, forKey: .insuranceAccepted) ?? []
       self.baseURL = try? container.decodeIfPresent(String.self, forKey: .baseURL) ?? ""
       self.headhshot = try container.decodeIfPresent(Headshot.self, forKey: .headhshot)
       //self.expertises = try? container.decodeIfPresent([String].self, forKey: .expertises) ?? []
       self.meta = try container.decodeIfPresent(Meta.self, forKey: .meta)
   



let json2 = """

   "acceptingNewPatients": true,
   "address": 
       "line1": "111 7th Ave",
       "city": "New York",
       "region": "NY",
       "postalCode": "10005",
       "countryCode": "US"
   ,
   "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
   "name": "John Doe",
   "cityCoordinate": 
       "latitude": 41.78200149536133,
       "longitude": -72.83170318603516
   ,
   "c_baseURL": "https://some-url.dummy.com/my-profile/current",
   "headshot": 
       "url": "https://some-url.dummy.com/my-profile/current/p/ooREDemnhmfahTVexnEyXRC4GTfeKdCDWgUr-GRL11Y/199x199.png",
       "width": 199,
       "height": 199,
       "sourceUrl": "https://some-url.dummy.com/my-profile/current/p/ooREDemnhmfahTVexnEyXRC4GTfeKdCDWgUr-GRL11Y/199x199.png",
       "thumbnails": [
           "url": "https://some-url.dummy.com/my-profile/current/p/ooREDemnhmfahTVexnEyXRC4GTfeKdCDWgUr-GRL11Y/196x196.png",
           "width": 196,
           "height": 196
       ]
   ,
   "insuranceAccepted": ["Finibus", "anything", "hidden", "consectetur" ],
   "meta": 
       "accountId": "967081498762345229",
       "uid": "Nd28v0",
       "id": "5119-13270",
       "timestamp": "2021-03-24T12:10:36",
       "labels": ["61280", "61288", "84273", "117907", "122937", "126160"],
       "folderId": "351068",
       "schemaTypes": ["therefore", "popular", "commodo", "voluptatem"],
       "language": "en",
       "countryCode": "US",
       "entityType": "informationProfessional"
   


""".data(using: .utf8)!

do 
let person = try JSONDecoder().decode(Person.self, from:json2)
print(person)
 catch let error 
    print(error)

它打印Person,请试一试,如果抛出任何错误,请在项目中尝试,而不是Playground或在线编译器。

【讨论】:

感谢您的回复!我在 Playground 中运行了您的代码,并收到了这条消息 valueNotFound(__lldb_expr_39.Person, Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data did not contain a top-level value.", underlyingError: nil) )。 好的,我在tutorialspoint.com/compile_swift_online.php 上尝试了同样的方法,它对我来说工作正常。过段时间我会去 Playground 看看。 在一个真实的项目中它可以工作。当然,它也适用于 tutorialpoints.com。我会接受你的回答。谢谢!

以上是关于Swift JSONDecoder 解码错误:错误:执行被中断,原因:EXC_BAD_ACCESS (code=1, address=0x5e48)的主要内容,如果未能解决你的问题,请参考以下文章

Swift JSON解码器类型不匹配错误

Swift 4 JSONDecoder 解码协议类型

如何在 swift 4.1 和 xcode 9.3 中使用 JSONDecoder 解码嵌套的 JSON 数组和对象?

使用 JSONDecoder 解码 [[String]]?

Swift4 JSONDecoder 期望解码 Dictionary<String, Any> 但找到了一个数组 [重复]

使用 JSONDecoder Swift 解码具有整数值的字符串键 [关闭]