NSKeyedUnarchiver解码始终返回nil的问题求助
问题诊断与修复方案
你的问题核心出在编码和解码的方法不匹配,NSKeyedArchiver是基于键值对的归档方案,而你当前的代码没有正确使用键相关的API,或者可以更简单地用便捷方法来处理整个根对象的归档。
一、编码环节的问题
你手动初始化了NSKeyedArchiver,但调用的encodeObject:是NSCoder的基础方法,在键式归档场景下这种写法没有把数组正确作为根对象归档,导致解码时无法识别。推荐用更简洁的便捷方法完成归档:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths firstObject]; NSString *fullFileName = [documentsDirectory stringByAppendingPathComponent:@"sessionDataSaveFile"]; NSError *archiveError = nil; NSData *pData = [NSKeyedArchiver archivedDataWithRootObject:self.sessionData requiringSecureCoding:NO error:&archiveError]; if (pData && !archiveError) { [pData writeToFile:fullFileName atomically:YES]; } else { NSLog(@"归档失败:%@", archiveError.localizedDescription); }
这个方法会自动把你的NSMutableArray作为根对象完成归档,省去手动初始化archiver、拼接数据的步骤,避免手动操作可能带来的错误。
二、解码环节的问题
你用decodeObject:获取数据,但这个方法在NSKeyedUnarchiver中需要对应编码时的键,而你编码时未指定键,自然取不到数据。同样用便捷方法解码根对象:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths firstObject]; NSString *fullFileName = [documentsDirectory stringByAppendingPathComponent:@"sessionDataSaveFile"]; NSData *pData = [NSData dataWithContentsOfFile:fullFileName]; if (pData) { NSError *unarchiveError = nil; self.sessionData = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:pData requiringSecureCoding:NO error:&unarchiveError]; if (!self.sessionData && unarchiveError) { NSLog(@"解档失败:%@", unarchiveError.localizedDescription); } }
这个方法会直接取出归档的根对象(也就是你的NSMutableArray),同时能捕获解码时的错误,方便你进一步排查问题。
三、额外检查点
即使修正了归档代码,也要确保自定义对象正确实现NSCoding协议:
- 必须实现
- (void)encodeWithCoder:(NSCoder *)coder和- (instancetype)initWithCoder:(NSCoder *)coder方法 - 编码和解码时的键要完全对应,比如编码用
[coder encodeObject:self.name forKey:@"name"],解码就要用_name = [coder decodeObjectForKey:@"name"] - 如果App部署目标是iOS 12+,即使禁用了secure coding,建议在自定义类中实现
+ (BOOL)supportsSecureCoding并返回YES
为什么原始代码会失败?
你手动初始化NSKeyedArchiver后调用encodeObject:,相当于向归档中添加了一个无键对象,但NSKeyedUnarchiver默认基于键查找数据,所以decodeObject:无法找到对应内容。另外你手动把archiver的encodedData追加到另一个NSMutableData的步骤完全多余,encodedData本身就是完整的归档数据。
内容的提问来源于stack exchange,提问作者DaveMoore
相关产品推荐
相关产品推荐

