作为框架导入后 NSKeyedUnarchiver decodeObjectForKey 崩溃

NSKeyedUnarchiver decodeObjectForKey crash after importing as a framework

在将 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")
    }
}

MyClass 拉入带有 CocoaPods 的框架后,我开始遇到这些崩溃:

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;
}

知道为什么吗?...

通过将此 class 移动到一个框架中,您已经更改了它的全名。在此之前可能是 MyApp.MyClass,但现在是 MyFramework.MyClass。键控归档不知道它们是相同的,这就是导致您出现问题的原因。删除并重新安装可以解决问题,因为不再有任何旧数据可以解码。

可以通过setClass(:forClassName:)告诉解压进程如何解决冲突,从而控制class/name匹配。你会做类似

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

这将解决解码问题。为了保持往返 encoding/decoding 正常工作,您可能需要做同样的事情来归档,比如

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