NSKeyedArchiver归档文件因外部框架缺失崩溃,如何修复?
解决NSKeyedUnarchiver因移除外部框架导致的崩溃问题
首先明确核心问题:NSKeyedUnarchiver在解归档时,是根据对象的完全限定类名(格式为框架名.类名)来查找对应类的。移除外部框架后,系统找不到原来的MyMobileKit.MyMobileKit_Token类,因此崩溃。下面针对你的疑问逐一解答,并提供更优方案:
关于使用typealias的可行性
- 直接用
typealias Token = MyMobileKit_Token完全不可行。typealias只是编译期的别名,不会改变运行时的类标识。解归档时系统依然会尝试查找MyMobileKit.MyMobileKit_Token,而你的本地Token类的运行时标识是你的App名称.Token,两者不匹配,崩溃问题无法解决。
关于创建同名代理框架的可行性
- 这个方案是可行的。只要你创建的新框架命名为
MyMobileKit,框架内包含MyMobileKit_Token类,并且保证该类:- 继承关系与原类一致
- 正确实现
NSCoding协议,且编码/解码的属性Key、逻辑与原类完全匹配
那么NSKeyedUnarchiver就能成功解析归档文件。不过这个方案比较繁琐,需要维护一个额外的框架,后续如果有其他类依赖也需要同步处理。
更优方案:使用NSKeyedUnarchiver.setClass(_:forClassName:)映射类
- 这是最简单高效的解决方式,无需额外框架,只需在本地定义一个与原类属性匹配的
Token类,然后在解归档操作前添加类映射:// 本地定义Token类,实现NSCoding协议,属性与原MyMobileKit_Token一致 class Token: NSObject, NSCoding { // 原类的属性,比如tokenString等 var tokenString: String? required init?(coder: NSCoder) { tokenString = coder.decodeObject(forKey: "tokenString") as? String // 严格对应原类的解码逻辑 } func encode(with coder: NSCoder) { coder.encode(tokenString, forKey: "tokenString") // 对应原类的编码逻辑(如果后续需要重新归档的话) } } // 解归档前设置类映射,告诉系统用本地Token替代原框架类 NSKeyedUnarchiver.setClass(Token.self, forClassName: "MyMobileKit.MyMobileKit_Token") // 执行解归档操作 if let decodedObject = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(archiveData) { // 处理解码后的对象 } - 这个方法直接告诉NSKeyedUnarchiver:当遇到类名为
MyMobileKit.MyMobileKit_Token的归档对象时,使用本地的Token类来解析。完全不需要创建额外框架,也能完美解决崩溃问题。
关键注意事项
- 本地
Token类的属性必须与原MyMobileKit_Token的属性完全对应,包括属性名称、类型,否则解归档后属性值会丢失或错误。 - 如果原类有继承关系,本地类的继承链也要保持一致(比如原类继承自NSObject,本地类也要继承NSObject)。
内容的提问来源于stack exchange,提问作者user9041624
相关产品推荐
相关产品推荐

