作为框架导入后 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)
在将 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)