NSKeyedUnarchiver decodeObjectForKey:无法为键(NS.objects)解码 class 的对象
NSKeyedUnarchiver decodeObjectForKey: cannot decode object of class for key (NS.objects)
我浏览了整个 SO 但仍然没有答案。我的应用报告了这个问题:
Fatal Exception: NSInvalidUnarchiveOperationException
*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (App_Title.Products) for key (NS.objects); the
class may be defined in source code or a library that is not linked
我在#unarchiveObject:
之前已经做了 NSKeyedUnarchiver.setClass
func loadProducts() -> [Products]? {
NSKeyedUnarchiver.setClass(Products.self, forClassName: "Products")
let unarchivedData = NSKeyedUnarchiver.unarchiveObject(withFile: Products.ArchiveURL.path)
我的产品 class 以 @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 管理器的屏幕截图:
这导致代码中的这一行:
NSKeyedUnarchiver.setClass(Products.self, forClassName: "Products")
let unarchivedData = NSKeyedUnarchiver.unarchiveObject(withFile: Products.ArchiveURL.path)
带有@Objc 注释的产品class。
您似乎混淆了 Codable
和 NSCoding
。不要试图同时使用两者。 NSKeyedUnarchiver
属于 NSCoding
.
您的 class 包含 属性 符合列表的属性。删除 NSCoding
并仅使用 Codable
。 (顺便说一下,建议以单数形式命名 class Product
)。
删除与 NSCoding
相关的所有内容,包括协议一致性和 Codable
class 不必继承自 NSObject
(对象可以是甚至是结构)。
loadProducts
函数可以简化为
func loadProducts() throws -> [Product] {
let data = try Data(contentsOf: Product.ArchiveURL)
return try PropertyListDecoder().decode([Product].self, from: data)
}
将 thrown
错误移交给调用者是个好习惯
并删除 CodingKeys
,如果密钥与 属性 名称匹配,则不需要它们。
我浏览了整个 SO 但仍然没有答案。我的应用报告了这个问题:
Fatal Exception: NSInvalidUnarchiveOperationException *** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (App_Title.Products) for key (NS.objects); the class may be defined in source code or a library that is not linked
我在#unarchiveObject:
之前已经做了 NSKeyedUnarchiver.setClassfunc loadProducts() -> [Products]? {
NSKeyedUnarchiver.setClass(Products.self, forClassName: "Products")
let unarchivedData = NSKeyedUnarchiver.unarchiveObject(withFile: Products.ArchiveURL.path)
我的产品 class 以 @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 管理器的屏幕截图:
这导致代码中的这一行:
NSKeyedUnarchiver.setClass(Products.self, forClassName: "Products")
let unarchivedData = NSKeyedUnarchiver.unarchiveObject(withFile: Products.ArchiveURL.path)
带有@Objc 注释的产品class。
您似乎混淆了 Codable
和 NSCoding
。不要试图同时使用两者。 NSKeyedUnarchiver
属于 NSCoding
.
您的 class 包含 属性 符合列表的属性。删除 NSCoding
并仅使用 Codable
。 (顺便说一下,建议以单数形式命名 class Product
)。
删除与 NSCoding
相关的所有内容,包括协议一致性和 Codable
class 不必继承自 NSObject
(对象可以是甚至是结构)。
loadProducts
函数可以简化为
func loadProducts() throws -> [Product] {
let data = try Data(contentsOf: Product.ArchiveURL)
return try PropertyListDecoder().decode([Product].self, from: data)
}
将 thrown
错误移交给调用者是个好习惯
并删除 CodingKeys
,如果密钥与 属性 名称匹配,则不需要它们。