gpt4 book ai didi

ios - 符合 Codable 协议(protocol)的类因 encodeWithCoder : unrecognized selector sent to instance 而失败

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

我知道有几个与此类似的问题,它们往往都围绕着未正确遵守协议(protocol)的类展开,但这不应该是这里的直接问题。

以下是目前给我这个问题的代码的浓缩版:

enum Binary: Int {
case a = 0
case b = 1
case c = 9
}

final class MyClass: NSCoder {
var string: String?
var date: Date?
var binary: Binary = .c

override init() { }

enum CodingKeys: CodingKey {
case string, date, binary
}
}

extension MyClass: Codable {
convenience init(from decoder: Decoder) throws {
self.init()

let values = try decoder.container(keyedBy: CodingKeys.self)
string = try values.decode(String.self, forKey: .string)
date = try values.decode(Date.self, forKey: .date)
binary = try Binary(rawValue: values.decode(Int.self, forKey: .binary)) ?? .c
}

func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(string, forKey: .string)
try container.encode(date, forKey: .date)
try container.encode(binary.rawValue, forKey: .binary)
}
}

我创建了以下类,然后尝试调用 MyClass 并将其写入和读取到 UserDefaults:

class MyClassController {
private let myClass: MyClass

init() {
self.myClass = MyClass()
self.myClass.string = "string"
self.myClass.date = Date()
self.myClass.binary = .a
}

func writeMyClass() {
let encodedData = NSKeyedArchiver.archivedData(withRootObject: myClass)
UserDefaults.standard.set(encodedData, forKey: String(describing: MyClass.self))
}

func readMyClass() {
if let decoded = UserDefaults.standard.object(forKey: String(describing: MyClass.self)) as? Data,
let myClass = NSKeyedUnarchiver.unarchiveObject(with: decoded as Data) as? MyClass {
print("string: \(myClass.string ?? "nil") date: \(myClass.date ?? Date()) binary: \(myClass.binary)")
}
}
}

不过,一旦调用 writeMyClass 函数,我就会收到此错误:

[DemoDecoder.MyClass encodeWithCoder:]: unrecognized selector sent to instance #blahblah#

我也试过两件事:

  • func encode(with aCoder: NSCoder) 添加到 MyClass
  • MyClass & CodingKeys 和 init/encode 函数中删除了所有属性

最佳答案

你有很多不匹配的尝试和各种编码/解码机制。

NSKeyedArchiverNSKeyedUnarchiver 要求所有涉及的类型都符合 NSCoding 协议(protocol)。这是来自 Objective-C 框架的旧机制。

协议(protocol) CodableEncoderDecoder 是 Swift 4 的新协议(protocol)。此类数据类型应与 Swift 编码器和解码器一起使用,例如作为 JSONEncoderJSONDecoderPropertyListEncoderPropertyListDecoder

我建议您删除对 NSCoder 的引用并删除对 NSKeyedArchiverNSKeyedUnarchiver 的使用。由于您已经实现了 Codable 协议(protocol),因此请使用合适的 Swift 编码器和解码器。在您的情况下,您想使用 PropertyListEncoderPropertyListDecoder

完成后,您可能应该将 MyClass 更改为 struct 而不是 class

您还应该避免使用 UserDefaults 来存储数据。而是将编码数据写入 plist 文件。

关于ios - 符合 Codable 协议(protocol)的类因 encodeWithCoder : unrecognized selector sent to instance 而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47659107/

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