我浏览了整个SO,但仍然没有答案。我的应用报告了此问题:
致命异常:NSInvalidUnarchiveOperationException ***-[NSKeyedUnarchiver encodeObjectForKey:]:无法为密钥(NS.objects)解码类(App_Title.Products)的对象;的 类可以在源代码或未链接的库中定义
我已经在#unarchiveObject之前做过NSKeyedUnarchiver.setClass:
func loadProducts() -> [Products]? {
NSKeyedUnarchiver.setClass(Products.self, forClassName: "Products")
let unarchivedData = NSKeyedUnarchiver.unarchiveObject(withFile: Products.ArchiveURL.path)
我的产品类以@Objc开头:
import Foundation
@objc(Products)
class Products: NSObject, Codable, NSCoding { ... }
在上面添加两行似乎对人们有所帮助的行并没有给我带来任何运气。在他们之前和之后,他们都是相同的行为。我个人永远无法自己重现此问题。
在开发过程中,我一直密切关注peristance上的应用指南,并对其进行了多次审核。
就在NSKeyedArchiver之前,我检查文件是否存在:
let filePath = Products.ArchiveURL.path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: filePath) {
在屏幕截图中有一些其他信息。
我能找到真正异常描述的唯一地方是Firebase Crashalytics:
“崩溃”标签下Xcode Organizer的屏幕截图:
在代码中导致以下一行:
NSKeyedUnarchiver.setClass(Products.self, forClassName: "Products")
let unarchivedData = NSKeyedUnarchiver.unarchiveObject(withFile: Products.ArchiveURL.path)
带有@Objc批注的产品类。
答案 0 :(得分:3)
似乎您正在混用Codable
和NSCoding
。不要尝试同时使用两者。 NSKeyedUnarchiver
属于NSCoding
。
您的类包含符合属性列表的属性。删除NSCoding
并仅使用Codable
。 (通过这种方式,建议以单数形式Product
命名该类。)
删除与NSCoding
相关的所有内容,包括协议一致性,并删除与Codable
的类,不必使类必须从NSObject
继承(该对象甚至可以是一个结构)。 / p>
loadProducts
函数可以简化为
func loadProducts() throws -> [Product] {
let data = try Data(contentsOf: Product.ArchiveURL)
return try PropertyListDecoder().decode([Product].self, from: data)
}
将thrown
个错误移交给调用方是一个好习惯
并删除CodingKeys
,如果键与属性名称匹配,则不需要它们。