自从
NSKeyedUnarchiver.unarchiveTopLevelObjectWithData
自 macOS 14.0 起已被弃用我现在尝试使用类中设置的 NSSecureCoding 加载旧版 NSCoder 档案并使用:
coder.unarchivedObject(ofClasses classes: [AnyClass], from data: Data)
加载存档。存档加载并且可以提取大多数类成员。然而,Swift 数组总是输出 nil,尽管
coder.containsValue(forKey:)
返回真。数组编码为:
var pageUsesClearBackground: Array<Bool> = [true, true, true, true]
coder.encode(pageUsesClearBackground, forKey: "CB_KEY")
使用:
pageUsesClearBackground = coder.decodeObject(forKey: "CB_KEY") as? Array<Bool>
返回一个值为 0 的数组,即使我使用非 NSSecureCode 版本,该数组也会被填充。
pageUsesClearBackground [Bool] 0 values
我怀疑这与 Swift 中的数组是一个结构并且不符合 NSCoding 有关。奇怪的是它多年来一直在编码和解码它们。知道如何从 NSSecureCoding 之前制作的存档中检索作为数组的类成员吗?
显然,NSSecureCoding 非常安全,您甚至无法取回数据。
这里有一些示例代码,您可以在 Swift Playground 中运行,它允许您取消归档数组:
class Foo: NSObject, NSSecureCoding {
static var supportsSecureCoding: Bool { true }
override init() {
super.init()
}
func encode(with coder: NSCoder) {
// This is based on the array in your question
var pageUsesClearBackground: Array<Bool> = [true, true, true, true]
coder.encode(pageUsesClearBackground, forKey: "CB_KEY")
}
required init?(coder: NSCoder) {
// This happily unarchives the [Bool]
if let pageUsesClearBackground = coder.decodeObject(of: [NSArray.self, NSNumber.self], forKey: "CB_KEY") as? [Bool] {
print(pageUsesClearBackground) // Shows expected output
} else {
print("oops")
}
}
}
let foo = Foo()
let data = try NSKeyedArchiver.archivedData(withRootObject: foo, requiringSecureCoding: true)
let bar = try NSKeyedUnarchiver.unarchivedObject(ofClass: Foo.self, from: data)
NSSecureCoding
及相关类都是基于Objective-C的。您需要指定支持 NSCoding
(NSSecureCoding
) 的类型。因此,在取消存档时,您需要告诉取消存档者您有 NSArray
个 NSNumber
实例。这就是 Swift [Bool]
真正转换成的。