Codable CoreData模型解码崩溃:-[Land setGun:]未识别选择器问题
CoreData + Codable 解码崩溃问题求助
各位大佬,我最近在做iOS项目时遇到了个头疼的问题:想让CoreData的模型类同时遵循NSManagedObject(用于CoreData持久化)和Codable(用于JSON序列化/反序列化)协议,结果JSON解码器在反序列化到一半时直接崩溃,报错信息如下:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Land setGun:]: unrecognized selector sent to instance 0x60400028f780'
我参考了Stack Overflow上《How to use swift 4 Codable in Core Data?》的指南,但有两个点实在搞不懂:
- 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数据模型如下:
如果以上信息还不足以定位问题,大家可以克隆我的公开GitHub仓库本地运行排查,仓库里有完整的项目代码。
内容的提问来源于stack exchange,提问作者James Jordan Taylor
相关产品推荐
相关产品推荐

