NSKeyedUnarchiver encodeObjectForKey:无法为密钥解码类的对象(NS.objects) [英] NSKeyedUnarchiver decodeObjectForKey: cannot decode object of class for key (NS.objects)

查看:136
本文介绍了NSKeyedUnarchiver encodeObjectForKey:无法为密钥解码类的对象(NS.objects)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我浏览了整个SO,但仍然没有答案.我的应用报告了此问题:

致命异常:NSInvalidUnarchiveOperationException***-[NSKeyedUnarchiver encodeObjectForKey:]:无法为密钥(NS.objects)解码类(App_Title.Products)的对象;这类可以在源代码或未链接的库中定义

我已经在#unarchiveObject之前做过NSKeyedUnarchiver.setClass:

  func loadProducts()->[产品]?{NSKeyedUnarchiver.setClass(Products.self,forClassName:产品")让unarchivedData = NSKeyedUnarchiver.unarchiveObject(withFile:Products.ArchiveURL.path) 

我的产品类以@Objc开头:

  import Foundation@objc(产品)类产品:NSObject,Codable,NSCoding {...} 

在上面添加两行似乎对人们有所帮助的行并没有给我带来任何运气.在他们之前和之后,他们都是相同的行为.我个人无法自己重现此问题.

在开发过程中,我非常密切地关注

崩溃"标签下Xcode Organizer的屏幕截图:

在代码中导致以下一行:

  NSKeyedUnarchiver.setClass(Products.self,forClassName:产品")让unarchivedData = NSKeyedUnarchiver.unarchiveObject(withFile:Products.ArchiveURL.path) 

带有@Objc批注的产品类.

解决方案

似乎您正在混淆 Codable NSCoding .不要尝试同时使用两者. NSKeyedUnarchiver 属于 NSCoding .

您的类包含符合属性列表的属性.删除 NSCoding 并仅使用 Codable .(通过这种方式,建议以单数形式 Product 命名该类.)

删除与 NSCoding 相关的所有内容,包括协议一致性和 Codable ,该类不必继承自 NSObject (对象甚至可以是一个结构).

loadProducts 函数可以简化为

  func loadProducts()抛出->[产品] {让数据=尝试数据(contentsOf:Product.ArchiveURL)返回尝试PropertyListDecoder().decode([Product] .self,from:data)} 

优良作法是将 Throwing 错误移交给调用方

并删除 CodingKeys ,如果键与属性名称匹配,则不需要它们.

I looked through whole SO but still no answer. My app reports this problem:

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

I did already do NSKeyedUnarchiver.setClass just before #unarchiveObject:

func loadProducts() -> [Products]? {
    NSKeyedUnarchiver.setClass(Products.self, forClassName: "Products")
    let unarchivedData = NSKeyedUnarchiver.unarchiveObject(withFile: Products.ArchiveURL.path)

My Products class begins with @Objc:

import Foundation

@objc(Products)
class Products: NSObject, Codable, NSCoding { ... }

Adding the two lines above which seemed to help people didn't bring me any luck. Before them and after them it's the same behaviour. I personally could never reproduce this issue myself.

During development I keep very closely to the app guide on peristance and reviewed it multiple times.

Just before NSKeyedArchiver I check for file existance:

let filePath = Products.ArchiveURL.path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: filePath) {

Here some additional informations in screenshots.

The only place where I could find a real exception description was Firebase Crashalytics:

A screenshot from the Xcode Organizer under the Crash tab:

Which leads to this line in the code:

NSKeyedUnarchiver.setClass(Products.self, forClassName: "Products")
let unarchivedData = NSKeyedUnarchiver.unarchiveObject(withFile: Products.ArchiveURL.path)

Products class with @Objc annotation.

解决方案

It seems that you are mixing up Codable and NSCoding. Don't try to use both simultaneously. NSKeyedUnarchiver belongs to NSCoding.

Your class contains property list compliant properties. Drop NSCoding and use only Codable. (By the way it's recommended to name the class in singular form Product).

Delete everything which is related to NSCoding including the protocol conformance and with Codable it's not necessary that the class must inherit from NSObject (the object can be even a struct).

The loadProducts function can be reduced to

func loadProducts() throws -> [Product] {
    let data = try Data(contentsOf: Product.ArchiveURL)
    return try PropertyListDecoder().decode([Product].self, from: data)
}

It's good practice to hand over thrown errors to the caller

And delete the CodingKeys, you don't need them if the keys match the property names.

这篇关于NSKeyedUnarchiver encodeObjectForKey:无法为密钥解码类的对象(NS.objects)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆