Swift 4中Decodable结合Realm列表持久化异常问题排查
嗨,我来帮你揪出这个问题的根源~
首先看你代码里的几个关键问题:
1. 漏掉了Realm父类的初始化调用
这是最核心的问题!Realm的Object子类在自定义init(from:)初始化方法时,必须调用super.init(),否则Realm无法正确初始化对象的内部存储结构——你解析出来的fooList虽然在内存里看起来正常,但因为父类没初始化,Realm没法把这个List的数据持久化到数据库,所以从Realm读取时就变成空的了。
2. CodingKey使用错误(大概率是笔误)
你在解析foo列表的时候写的是:
try? container.decode([Foo].self, forKey: .id)
这里的.id是对应id字段的Key,根本不是foo列表的字段Key啊!这会导致你完全没解析到fooList的数据(不过你说序列化后检查数据正常,估计是代码里写错了,应该是.fooList这类对应JSON字段的Key)。
3. try?隐藏了潜在错误
用try?会把解析过程中的错误直接吞掉,哪怕fooList解析失败你也不知道,建议换成try,这样能及时捕获问题。
修正后的完整代码示例
还要注意,Realm的Object子类如果自定义了初始化方法,必须实现另外两个Realm要求的初始化方法,同时补上CodingKeys枚举来映射JSON字段:
class MyObj: RealmSwift.Object, Decodable { dynamic var id: String = "" let fooList = List<Foo>() // 定义JSON字段对应的CodingKeys,字段名要和你的JSON结构一致 enum CodingKeys: String, CodingKey { case id case fooList } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // 解析id字段 id = try container.decode(String.self, forKey: .id) // 正确解析foo列表,用对应CodingKey,并且不要吞错误 let fooArray = try container.decode([Foo].self, forKey: .fooList) fooArray.forEach(fooList.append) // 关键:必须调用父类初始化 super.init() } // Realm要求的空初始化方法 required init() { super.init() } // Realm要求的数据库初始化方法 required init(realm: RLMRealm, schema: RLMObjectSchema) { super.init(realm: realm, schema: schema) } override class func primaryKey() -> String? { return "id" } }
另外还要确保Foo类也是Realm的Object子类并且正确实现了Decodable,否则解析数组时也会出问题。
内容的提问来源于stack exchange,提问作者Giuseppe Lanza
相关产品推荐
相关产品推荐

