gpt4 book ai didi

swift - 当我不知道类型时,如何使用类继承进行解码?

转载 作者:可可西里 更新时间:2023-11-01 01:59:53 25 4
gpt4 key购买 nike

我有一个基类Action,它是一个Operation。它里面有一堆笨拙的 Operation 东西(KVO 等等)。基类本身实际上不需要编码/解码任何东西。

class Action : Operation, Codable {
var _executing = false
...
}

我有一堆 Action 子类,比如 DropboxUploadAction,它们直接用它们定义的 Input 结构实例化:

let actionInput = DropboxUploadAction.Input.init(...)
ActionManager.shared.run(DropboxUploadAction.init(actionInput, data: binaryData), completionBlock: nil)

这是子类的样子:

class DropboxUploadAction : Action {
struct Input : Codable {
var guid: String
var eventName: String
var fileURL: URL?
var filenameOnDropbox: String
var share: Bool
}

struct Output : Codable {
var sharedFileLink: String?
var dropboxPath: String?
}

var input: Input
var output: Output

...

required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
input = try values.decode(Input.self, forKey: .input)
output = try values.decode(Output.self, forKey: .output)
let superDecoder = try values.superDecoder()
try super.init(from: superDecoder)
}

fileprivate enum CodingKeys: String, CodingKey {
case input
case output
}

override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(input, forKey: .input)
try container.encode(output, forKey: .output)
try super.encode(to: container.superEncoder())
}
}

当某些情况发生时,例如丢失 Internet 连接,这些类需要序列化到磁盘以备后用。这很好,因为当时我有对它们的引用并且可以使用 JSONEncoder().encode(action) 对它们进行编码,没问题。

但是后面想反序列化的时候,需要指定类的类型,不知道是什么。我有一些数据,我知道它可以被解码为一个继承自 Action 的类,但我不知道它是哪个子类。我讨厌在文件名中对其进行编码。有没有办法将它解码为基类 Action,然后在 Actiondecode() 方法中,以某种方式检测正确的类和重定向?

过去我使用 NSKeyedUnarchiver.setClass() 来处理这个问题。但我不知道如何使用 Swift 4 的 Codable 做到这一点,而且我知道 NSCoding 现在已被弃用,所以我不应该再使用 NSKeyedUnarchiver...

如果有帮助:我有一个 struct Types : OptionSet, Codable 每个子类都返回它,所以我不必使用类的名称作为它的标识。

感谢您的帮助!

最佳答案

Uhhh NSCoding 没有弃用。我们在通过 init(coder:) 从 Storyboard实例化 UIViewControllers 时仍然使用它。

此外,如果您仍然不想使用 NSCoding,您可以只存储 InputOutputTypes 到结构并将其序列化到磁盘。

struct SerializedAction {
let input: Input
let output: Output
let type: Type
}

在需要时,您可以对其进行解码并确定正确的Action 以通过type 属性使用您的输入/输出进行初始化。

class DropboxAction: Action {
...
init(input: Input, output: Output) {
...
}
}

您不一定需要对整个 Action 对象进行编码。

关于swift - 当我不知道类型时,如何使用类继承进行解码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47563266/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com