decodeObjectOfClasses返回nil原因及forKey参数取值疑问
问题分析与解答
一、为什么unarchivedDict返回nil?
你通过[NSKeyedArchiver archivedDataWithRootObject:dict ...]把整个NSDictionary作为根对象归档时,归档数据的顶层结构里,整个字典被绑定在@"root"(系统常量NSKeyedArchiveRootObjectKey)这个键下。而字典内部的@"key1"是字典自身的键,并不是归档时的顶层键。
你直接调用decodeObjectOfClasses:forKey:@"key1"去顶层查找该键,自然找不到对应的值,所以返回nil。
二、是否必须使用decodeObjectForKey:?
不是必须,但如果要从归档数据中提取指定的顶层对象,需要使用它(或带类型校验的decodeObjectOfClasses:forKey:)。针对你的场景,正确的做法是先解码出整个根字典,再从字典中取出@"key1"对应的值:
// 解码出整个根字典 NSDictionary *unarchivedFullDict = [unarchiver decodeObjectOfClasses:[NSSet setWithObjects:[NSDictionary class], [NSString class], [NSNumber class], nil] forKey:NSKeyedArchiveRootObjectKey]; // 从字典中提取key1的值 NSString *value1 = unarchivedFullDict[@"key1"]; NSLog(@"value1: %@", value1);
注:NSKeyedArchiveRootObjectKey是系统预定义常量,和@"root"等价
三、forKey可使用哪些值?
forKey的取值完全由归档时绑定的顶层键决定:
- 若使用
archivedDataWithRootObject:归档,根对象固定绑定在NSKeyedArchiveRootObjectKey(即@"root")下,只能通过这个键提取根对象。 - 若手动创建
NSKeyedArchiver自定义归档流程(比如用encodeObject:forKey:给不同对象绑定不同顶层键),解码时就可以使用归档时定义的所有顶层键。
示例:自定义归档与解码
// 自定义归档流程 NSMutableData *customArchiveData = [NSMutableData data]; NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:customArchiveData]; [archiver encodeObject:@"value1" forKey:@"key1"]; [archiver encodeObject:@(42) forKey:@"key2"]; [archiver finishEncoding]; // 对应解码 NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:customArchiveData error:nil]; NSString *val1 = [unarchiver decodeObjectOfClass:[NSString class] forKey:@"key1"]; NSNumber *val2 = [unarchiver decodeObjectOfClass:[NSNumber class] forKey:@"key2"]; [unarchiver finishDecoding];
内容的提问来源于stack exchange,提问作者n0bod1
相关产品推荐
相关产品推荐

