gpt4 book ai didi

swift - NSCoding 和 Codable 可以共存吗?

转载 作者:搜寻专家 更新时间:2023-10-31 22:39:23 24 4
gpt4 key购买 nike

在测试新 Codable 如何与 NSCoding 交互时,我整理了一个 playground 测试,涉及使用包含 Codable 结构的 Class 的 NSCoding。惠特

struct Unward: Codable {
var id: Int
var job: String
}

class Akward: NSObject, NSCoding {

var name: String
var more: Unward

init(name: String, more: Unward) {
self.name = name
self.more = more
}

func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
aCoder.encode(more, forKey: "more")
}

required init?(coder aDecoder: NSCoder) {
name = aDecoder.decodeObject(forKey: "name") as? String ?? ""
more = aDecoder.decodeObject(forKey: "more") as? Unward ?? Unward(id: -1, job: "unk")
super.init()
}
}

var upone = Unward(id: 12, job: "testing")
var adone = Akward(name: "Adrian", more: upone)

Playground 接受以上内容,不会产生任何编译器错误。

但是,如果我像这样尝试 Saving adone:

let encodeit = NSKeyedArchiver.archivedData(withRootObject: adone)

Playground 立即因错误而崩溃:

error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).

为什么?有没有办法让 NSCoding 类包含 Codable 结构?

最佳答案

您得到的实际错误是:

-[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance

这是来自行:

aCoder.encode(more, forKey: "more")

问题的原因是more(类型Unward)不符合NSCoding。但是 Swift struct 不能符合 NSCoding。除了符合 NSCoding 之外,您还需要将 Unward 更改为扩展 NSObject 的类。这些都不会影响符合 Codable 的能力。

这是您更新后的类(class):

class Unward: NSObject, Codable, NSCoding {
var id: Int
var job: String

init(id: Int, job: String) {
self.id = id
self.job = job
}

func encode(with aCoder: NSCoder) {
aCoder.encode(id, forKey: "id")
aCoder.encode(job, forKey: "job")
}

required init?(coder aDecoder: NSCoder) {
id = aDecoder.decodeInteger(forKey: "id")
job = aDecoder.decodeObject(forKey: "job") as? String ?? ""
}
}

class Akward: NSObject, Codable, NSCoding {
var name: String
var more: Unward

init(name: String, more: Unward) {
self.name = name
self.more = more
}

func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
aCoder.encode(more, forKey: "more")
}

required init?(coder aDecoder: NSCoder) {
name = aDecoder.decodeObject(forKey: "name") as? String ?? ""
more = aDecoder.decodeObject(forKey: "more") as? Unward ?? Unward(id: -1, job: "unk")
}
}

还有你的测试值:

var upone = Unward(id: 12, job: "testing")
var adone = Akward(name: "Adrian", more: upone)

您现在可以归档和取消归档:

let encodeit = NSKeyedArchiver.archivedData(withRootObject: adone)
let redone = NSKeyedUnarchiver.unarchiveObject(with: encodeit) as! Akward

你可以编码和解码:

let enc = try! JSONEncoder().encode(adone)
let dec = try! JSONDecoder().decode(Akward.self, from: enc)

关于swift - NSCoding 和 Codable 可以共存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50746595/

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