使用 "Codable" 设置 属性 值在继承中不起作用
Using "Codable" to set property values doesn't work through inheritance
我无法在 child class 中设置 b
属性。它是继承自 Codable
的 parent class,并且似乎运行良好。
我觉得我错过了一些非常明显的东西,但我很难只见树木不见森林。
下面是我的问题的游乐场示例。尽管设置为 10
,b
仍为 0。传入的是childclass,但是可以设置parent属性(很奇怪!)。
class Primary : Codable {
var a: Int = 0
}
class Secondary : Primary {
var b: Int = 0
}
let c = Secondary.self
func testRef<T: Codable>(_ t: T.Type) {
let json = "{\"a\":5, \"b\" : 10}".data(using: .ascii)!
let testCodable = try? JSONDecoder().decode(t.self, from: json)
print("a >> \((testCodable as! Primary).a)")
print("b >> \((testCodable as! Secondary).b)")
}
testRef(c)
这个输出是:
a >> 5
b >> 0
如有任何提示或指点,我们将不胜感激。
- 在 Xcode 9.3、Swift 4.1
中尝试过
Codable
的魔力在于简单(使用不支持继承的结构)。
自定义越多代码越多
你必须在 subclass 中编写一个自定义初始化器来考虑继承(感谢 Hamish 的注释,CodingKeys 和初始化器是在基础 class), 我故意省略了 Encodable
部分
class Primary : Decodable {
var a: Int
/*
private enum CodingKeys: String, CodingKey { case a }
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
a = try container.decode(Int.self, forKey: .a)
}
*/
}
class Secondary : Primary {
var b: Int
private enum CodingKeys: String, CodingKey { case b }
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
b = try container.decode(Int.self, forKey: .b)
try super.init(from: decoder)
}
}
func testRef<T: Decodable>() throws -> T {
let json = "{\"a\":5, \"b\" : 10}".data(using: .utf8)!
return try JSONDecoder().decode(T.self, from: json)
}
do {
let secondary : Secondary = try testRef()
print(secondary.a, secondary.b) // 5 10
} catch { print(error) }
我无法在 child class 中设置 b
属性。它是继承自 Codable
的 parent class,并且似乎运行良好。
我觉得我错过了一些非常明显的东西,但我很难只见树木不见森林。
下面是我的问题的游乐场示例。尽管设置为 10
,b
仍为 0。传入的是childclass,但是可以设置parent属性(很奇怪!)。
class Primary : Codable {
var a: Int = 0
}
class Secondary : Primary {
var b: Int = 0
}
let c = Secondary.self
func testRef<T: Codable>(_ t: T.Type) {
let json = "{\"a\":5, \"b\" : 10}".data(using: .ascii)!
let testCodable = try? JSONDecoder().decode(t.self, from: json)
print("a >> \((testCodable as! Primary).a)")
print("b >> \((testCodable as! Secondary).b)")
}
testRef(c)
这个输出是:
a >> 5
b >> 0
如有任何提示或指点,我们将不胜感激。
- 在 Xcode 9.3、Swift 4.1 中尝试过
Codable
的魔力在于简单(使用不支持继承的结构)。
自定义越多代码越多
你必须在 subclass 中编写一个自定义初始化器来考虑继承(感谢 Hamish 的注释,CodingKeys 和初始化器是在基础 class), 我故意省略了 Encodable
部分
class Primary : Decodable {
var a: Int
/*
private enum CodingKeys: String, CodingKey { case a }
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
a = try container.decode(Int.self, forKey: .a)
}
*/
}
class Secondary : Primary {
var b: Int
private enum CodingKeys: String, CodingKey { case b }
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
b = try container.decode(Int.self, forKey: .b)
try super.init(from: decoder)
}
}
func testRef<T: Decodable>() throws -> T {
let json = "{\"a\":5, \"b\" : 10}".data(using: .utf8)!
return try JSONDecoder().decode(T.self, from: json)
}
do {
let secondary : Secondary = try testRef()
print(secondary.a, secondary.b) // 5 10
} catch { print(error) }