You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 22:43:24