Swift 尝试将 Codable 父 class 解码为其子 class 之一
Swift Attempt to a decode a Codable parent class as one of its subclasses
假设我有父 class A: Codable
和子 class 是 B1: A
和 B2: A
。我的应用程序中的另一个 class Main: Codable
有一个指向 A
的指针,它可以是 B1
或 B2
但不能是 A
(我有效地将 A
视为抽象 class)。
当我解码 Main
时,我 运行 遇到了一个问题,它被错误地解码为摘要 A
而不是 B1
或 B2
,即使存储在 A
中的值始终是 B1
或 B2
。我已经尝试在子 classes 中实现自定义 init(from decoder: Decoder)
和 func encode(to encoder: Encoder)
s,但是当我逐步执行被调用的 Main
's decode logic in my running app, I never see those subclasses' 实现时。
这是因为 Main
有一个 A
,甚至不知道尝试将其解码为 B1
或 B2
?我需要专门调用那些 subclasses 解码器吗?如果是后者,那些子classes 解码器将无法调用父解码器,因为那样会造成无限循环。
这是我的代码目前的样子:
class Main: Codable {
let a: A
}
class A: Codable {
}
class B1: A {
let b1Only: Int
private enum CodingKeys: String, CodingKey {
case b1Only
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
b1Only = try container.decode(Int.self, forKey: .b1Only)
try super.init(from: decoder)
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.b1Only, forKey: .b1Only)
try super.encode(to: encoder)
}
}
class B2: A {
let b2Only: Int
private enum CodingKeys: String, CodingKey {
case b2Only
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
b2Only = try container.decode(Int.self, forKey: .b2Only)
try super.init(from: decoder)
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.b2Only, forKey: .b2Only)
try super.encode(to: encoder)
}
}
你需要在Main
中有一个自定义的init(from:)
并直接解码a
到正确的子类
class Main: Codable {
let a: A
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if let object = try? container.decode(B1.self, forKey: .a) {
a = object
} else {
a = try container.decode(B2.self, forKey: .a)
}
}
}
假设我有父 class A: Codable
和子 class 是 B1: A
和 B2: A
。我的应用程序中的另一个 class Main: Codable
有一个指向 A
的指针,它可以是 B1
或 B2
但不能是 A
(我有效地将 A
视为抽象 class)。
当我解码 Main
时,我 运行 遇到了一个问题,它被错误地解码为摘要 A
而不是 B1
或 B2
,即使存储在 A
中的值始终是 B1
或 B2
。我已经尝试在子 classes 中实现自定义 init(from decoder: Decoder)
和 func encode(to encoder: Encoder)
s,但是当我逐步执行被调用的 Main
's decode logic in my running app, I never see those subclasses' 实现时。
这是因为 Main
有一个 A
,甚至不知道尝试将其解码为 B1
或 B2
?我需要专门调用那些 subclasses 解码器吗?如果是后者,那些子classes 解码器将无法调用父解码器,因为那样会造成无限循环。
这是我的代码目前的样子:
class Main: Codable {
let a: A
}
class A: Codable {
}
class B1: A {
let b1Only: Int
private enum CodingKeys: String, CodingKey {
case b1Only
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
b1Only = try container.decode(Int.self, forKey: .b1Only)
try super.init(from: decoder)
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.b1Only, forKey: .b1Only)
try super.encode(to: encoder)
}
}
class B2: A {
let b2Only: Int
private enum CodingKeys: String, CodingKey {
case b2Only
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
b2Only = try container.decode(Int.self, forKey: .b2Only)
try super.init(from: decoder)
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.b2Only, forKey: .b2Only)
try super.encode(to: encoder)
}
}
你需要在Main
中有一个自定义的init(from:)
并直接解码a
到正确的子类
class Main: Codable {
let a: A
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if let object = try? container.decode(B1.self, forKey: .a) {
a = object
} else {
a = try container.decode(B2.self, forKey: .a)
}
}
}