首页 > 解决方案 > Codable CoreData 模型因“无法识别的选择器发送到实例”而崩溃

问题描述

因此,我正在尝试使我的模型类符合NSManagedObject(用于 CoreData 持久性)和Codable(用于 JSON 序列化/反序列化)。现在,我的 JSON 解码器在反序列化过程中大约完成了一半,然后它因错误而崩溃

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Land setGun:]: unrecognized selector sent to instance 0x60400028f780'

我一直在遵循此处找到的两种模型协议的一致性指南How to use swift 4 Codable in Core Data? 我意识到抛出错误是因为(如果要相信错误) Land 类没有“setGun”方法。让我感到困惑的是

A) 在我解码 Land 类 JSON 时不会发生错误(它可以毫无问题地处理),最后一个要命中的断点实际上是在 Sea 类的 JSON 解码器中。

B) Land 类确实有一个“setGun”方法(我在该类中声明了一个占位符方法,以防万一它与自动生成的 CoreData 代码有关)。

我的 Land 类代码如下:

import Foundation
import CoreData
@objc(Land)
class Land : NSManagedObject, Equipment {
var type = EquipmentType.LAND

enum CodingKeys: String, CodingKey {
    case id
    case name
    case desc = "description"
    case groupIconUrl
    case individualIconUrl
    case photoUrl
    case primaryWeapon
    case secondaryWeapon
    case atgm
    case armor
    case speed
    case auto
    case weight
}

required convenience init(from decoder: Decoder) throws {
    guard let context = decoder.userInfo[CodingUserInfoKey.context!] as? NSManagedObjectContext else { fatalError() }
    guard let entity = NSEntityDescription.entity(forEntityName: "Land", in: context) else { fatalError() }
    self.init(entity: entity, insertInto: context)
    let container = try! decoder.container(keyedBy: CodingKeys.self)
    self.id = try container.decode(Int64.self, forKey: .id)
    self.name = try container.decodeIfPresent(String.self, forKey: .name)
    self.desc = try container.decodeIfPresent(String.self, forKey: .desc)
    self.groupIconUrl = try container.decodeIfPresent(String.self, forKey: .groupIconUrl)
    self.individualIconUrl = try container.decodeIfPresent(String.self, forKey: .individualIconUrl)
    self.photoUrl = try container.decodeIfPresent(String.self, forKey: .photoUrl)
    self.primaryWeapon = try container.decodeIfPresent(Gun.self, forKey: .primaryWeapon)
    self.secondaryWeapon = try container.decodeIfPresent(Gun.self, forKey: .secondaryWeapon)
    self.atgm = try container.decodeIfPresent(Gun.self, forKey: .atgm)
    self.armor = try container.decode(Int64.self, forKey: .armor)
    self.speed = try container.decode(Int64.self, forKey: .speed)
    self.auto = try container.decode(Int64.self, forKey: .auto)
    self.weight = try container.decode(Int64.self, forKey: .weight)
}
public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(id, forKey: .id)
    try container.encode(name, forKey: .name)
    try container.encode(desc, forKey: .desc)
    try container.encode(groupIconUrl, forKey: .groupIconUrl)
    try container.encode(individualIconUrl, forKey: .individualIconUrl)
    try container.encode(photoUrl, forKey: .photoUrl)
    try container.encode(primaryWeapon, forKey: .primaryWeapon)
    try container.encode(secondaryWeapon, forKey: .secondaryWeapon)
    try container.encode(atgm, forKey: .atgm)
    try container.encode(armor, forKey: .armor)
    try container.encode(speed, forKey: .speed)
    try container.encode(auto, forKey: .auto)
    try container.encode(weight, forKey: .weight)
}
public func setGun(gun: Gun){}
}

我的 CoreData 数据模型也在屏幕下方:

CoreData 数据模型

最后,如果所有这些都不足以诊断出问题所在,您可以自由地克隆存储库并从以下公共 github 存储库在本地运行它:https ://github.com/jamesjmtaylor/weg-ios

标签: swiftcore-dataunrecognized-selectorcodable

解决方案


您在文件中的这一行中的问题Air.swift我真的不知道为什么不解码 Gun at Air file Decoder

self.gun = try container.decodeIfPresent(Gun.self, forKey: .gun)
self.agm = try container.decodeIfPresent(Gun.self, forKey: .agm)
self.aam = try container.decodeIfPresent(Gun.self, forKey: .aam)
self.asm = try container.decodeIfPresent(Gun.self, forKey: .asm)

推荐阅读