Swift 4中Encodable类继承时如何正确编码子类属性?
解决Swift 4中继承Encodable类的子类编码问题
这个问题在Swift 4的Encodable继承场景里挺常见的——当子类继承自一个已经实现Encodable的父类时,编译器不会自动为子类合成完整的编码逻辑,导致子类独有的属性无法被JSONEncoder识别。加上你的示例代码里子类的初始化方法还缺少对父类初始化的调用,咱们一步步来解决:
第一步:修正子类的初始化方法
你写的AdditionalData类初始化方法没有调用super.init(),这会直接导致编译错误(父类BasicData只有无参初始化器),先补上这一步:
class AdditionalData: BasicData { let c: String init(c: String) { self.c = c super.init() // 必须调用父类初始化器完成父类属性初始化 } }
第二步:手动实现子类的Encodable编码逻辑
编译器无法自动为继承Encodable的子类合成编码方法,所以需要我们手动实现encode(to:)方法,先让父类完成自身属性的编码,再处理子类独有的属性:
class AdditionalData: BasicData { let c: String init(c: String) { self.c = c super.init() } // 重写encode方法,整合父类与子类的编码逻辑 override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) // 先让父类编码a、b属性 var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(c, forKey: .c) // 编码子类独有的c属性 } // 定义子类专属的CodingKeys枚举 enum CodingKeys: String, CodingKey { case c } }
第三步:验证编码结果
现在运行你的测试代码,输出就会是你期望的:{"a":"a","b":"b","c":"c"}。
原理说明
- 默认情况下,编译器为
Encodable类型自动生成的encode(to:)方法只会处理当前类型的属性,不会主动触发父类的编码逻辑。 - 通过手动实现
encode(to:),先调用super.encode(to: encoder)让父类完成其属性的编码,再处理子类自己的属性,就能保证所有层级的属性都被正确编码。
如果你的父类也有自定义的CodingKeys,只需要确保子类的编码逻辑和父类的key不重复即可。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

