为啥 NSCoding 无法在正确保存后解码对象?

Posted

技术标签:

【中文标题】为啥 NSCoding 无法在正确保存后解码对象?【英文标题】:Why is NSCoding unable to decode an object once saved properly?为什么 NSCoding 无法在正确保存后解码对象? 【发布时间】:2020-01-14 19:19:26 【问题描述】:

这是我在核心数据中保存为可转换的完整类。

public class Item: NSObject, NSCoding 
    public var imageData: Data
    public var title: String
    public var keywords: [String]
    public var date: Date

    public init(imageData: Data, title: String, date: Date, keywords: [String])  
        self.imageData = imageData
        self.title = title
        self.date = date
        self.keywords = keywords
        super.init()
    

    public func encode(with coder: NSCoder) 
        coder.encode(imageData, forKey: "imageData")
        coder.encode(title, forKey: "title")
        coder.encode(keywords, forKey: "keywords")
        coder.encode(date.timeIntervalSince1970, forKey: "date")
    

    public required convenience init?(coder: NSCoder) 
        self.init(
            imageData: (coder.value(forKey: "imageData") as? Data) ?? Data(),
            title: (coder.value(forKey: "title") as? String) ?? "",
            date: Date(timeIntervalSince1970: (coder.value(forKey: "date") as? TimeInterval) ?? Date().timeIntervalSince1970),
            keywords: coder.value(forKey: "keywords") as? [String] ?? [])
    


我能够成功地将这些对象保存在核心数据中,但是当我获取这些对象时,它会在方法中崩溃 -> public required contrast init?(coder: NSCoder)

因为编码器找不到键的值。

这是我得到的错误,

由于未捕获的异常“NSUnknownKeyException”而终止应用程序, 原因:'[valueForUndefinedKey:]:这个 类不符合键 imageData 的键值编码。

我尝试过不同的转换器,我尝试过创建自己的。

我尝试将其保存为二进制数据,我也尝试创建一个关系数据库,但似乎没有任何效果。

我在这里做错了吗?

谢谢!

【问题讨论】:

【参考方案1】:

符合键值编码的属性必须标记为@objc dynamic

@objcMembers
public class Item: NSObject, NSCoding 
    dynamic public var imageData: Data
    dynamic public var title: String
    dynamic public var keywords: [String]
    dynamic public var date: Date

...

@objcMembers 是所有属性的全局指令

您应该使用适当的 API 来解码对象

public required convenience init?(coder aDecoder: NSCoder) 
    self.init(
        imageData: (aDecoder.decodeObject(forKey: "imageData") as? Data) ?? Data(),
        title: (aDecoder.decodeObject(forKey: "title") as? String) ?? "",
        date: Date(timeIntervalSince1970: aDecoder.decodeDouble(forKey: "date")),
        keywords: aDecoder.decodeObject(forKey: "keywords") as? [String] ?? [])

【讨论】:

CoreData: 故障:在多线程获取期间引发异常 [ valueForUndefinedKey:]:此类与键 imageData 的键值编码不兼容。 ( NSTargetObjectUserInfoKey = ""; NSUnknownUserInfoKey = imageData; )

以上是关于为啥 NSCoding 无法在正确保存后解码对象?的主要内容,如果未能解决你的问题,请参考以下文章

地图坐标不解码

使用 NSCoding Swift 保存对象时出现异常

runtime之实现对应序列化

如何使用 NSCoding 保存结构

使用 NSCoding 保存结构的 Helperclass

为啥在保存对象后使用“重新加载”方法? (Hartl Rails Tut 6.30)