【问题标题】:NSKeyedUnarchiver decodeObjectForKey crash after importing as a frameworkNSKeyedUnarchiver decodeObjectForKey 作为框架导入后崩溃
【发布时间】:2017-07-24 21:07:51
【问题描述】:

在将MyClass 提取到框架之前,我可以将MyClass 的实例保存到Core Data 中就好了。

这里是MyClass的实现:

open class MyClass: NSObject, NSCoding {
  required public init?(coder aDecoder: NSCoder) {
        super.init()
        stuffs = aDecoder.decodeObject(forKey: "stuff") as? [Stuff] ?? []
    }

    open func encode(with aCoder: NSCoder) {
        aCoder.encode(stuffs, forKey: "stuffs")
    }
}

在使用 CocoaPods 将 MyClass 拉出框架后,我开始遇到这些崩溃:

CoreData: error: exception handling request: <NSSQLFetchRequestContext: 0x1c019d4d0> , *** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (MyClass) for key (NS.objects); the class may be defined in source code or a library that is not linked with userInfo of {
    "__NSCoderInternalErrorCode" = 4864;
}

知道为什么吗?...

【问题讨论】:

  • 编辑:所以在我从手机中删除应用程序并重新安装后,一切正常...但是如果我需要推出更新,这将不起作用?...o从手机中删除应用程序并重新安装后,一切正常...但是如果我需要推出更新,这将不起作用?...

标签: ios core-data cocoapods nscoding nscoder


【解决方案1】:

通过将这个类移动到一个框架中,你已经改变了它的全名。在那之前应该是MyApp.MyClass,但现在是MyFramework.MyClass。密钥存档不知道它们是相同的,这就是导致您的问题的原因。删除并重新安装可以解决问题,因为不再有任何旧数据要解码。

您可以使用setClass(:forClassName:) 告诉取消归档进程如何解决冲突,以便您控制类/名称匹配。你会做类似的事情

NSKeyedUnarchiver.setClass(MyClass.self, forClassName: "MyApp.MyClass")

这将修复解码。为了保持往返编码/解码工作,您可能需要对归档执行相同的操作,例如

NSKeyedArchiver.setClassName("MyApp.MyClass", for: MyClass.self)

【讨论】:

  • 这正是发生的事情。非常感谢您的帮助!
  • 快速跟进问题:我正在尝试编写一些迁移逻辑,因为会有旧数据和新数据(没有以前的“脏”)数据的应用安装。您有快速检查这些情况的方法吗?
  • 如果您像上面这样添加正确的命名调用,您将能够解码现有数据。没有理由停止使用该名称。如果您愿意,您可以省略 NSArchiver 调用,新档案将使用框架名称。
  • 优秀的解决方案。我遇到了与 OP 类似的问题。正在归档/取消归档,然后将目标类移至框架。
猜你喜欢
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
  • 2011-08-07
  • 1970-01-01
  • 2012-09-04
  • 1970-01-01
  • 2011-11-25
  • 2016-02-15
相关资源
最近更新 更多