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

Objective-C中JSON数组替换异常:原因分析与解决方法

解决Objective-C中JSON对象替换的NSUnknownKeyException异常问题

我来帮你拆解这个问题并给出可行的解决方案:

异常的根本原因

你遇到的NSUnknownKeyException核心问题在于你把JSON字符串直接当成了可通过KVC访问的集合对象来操作:

  • 从NSUserDefaults获取的list1是NSString类型(你之前应该是把JSON字符串存在了UserDefaults里),而非NSDictionary或NSArray这类集合对象。
  • NSString类并不支持通过valueForKeyPath:@"innerList"来访问属性——它根本没有名为innerList的KVC键,所以系统抛出了这个异常。
  • 同样,你从文件读取的list2也是NSString类型,直接赋值给oldList(一个字符串变量)完全达不到替换数组的目的。

正确实现数组替换的步骤

要完成innerList替换为innerList2的需求,你需要先把JSON字符串解析成Objective-C的集合对象(NSDictionary/NSArray),修改后再根据需求转回JSON字符串(比如存回UserDefaults)。具体代码如下:

1. 解析JSON字符串为集合对象

// 从UserDefaults获取JSON字符串并解析为可变NSDictionary
NSString *list1JsonStr = [[NSUserDefaults standardUserDefaults] objectForKey:@"list1"];
NSData *list1Data = [list1JsonStr dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSMutableDictionary *list1Dict = [NSJSONSerialization JSONObjectWithData:list1Data 
                                                                 options:NSJSONReadingMutableContainers 
                                                                   error:&error];
if (error) {
    NSLog(@"解析list1失败: %@", error.localizedDescription);
    return;
}

// 从文件读取JSON字符串并解析为NSDictionary,再取出innerList2数组
NSString *list2JsonStr = [[NSString alloc] initWithContentsOfFile:filePath 
                                                         encoding:NSUTF8StringEncoding 
                                                            error:&error];
NSData *list2Data = [list2JsonStr dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *list2Dict = [NSJSONSerialization JSONObjectWithData:list2Data 
                                                           options:0 
                                                             error:&error];
if (error) {
    NSLog(@"解析list2失败: %@", error.localizedDescription);
    return;
}
NSArray *innerList2 = list2Dict[@"innerList2"];

2. 替换目标数组

因为list1Dict是可变字典(通过NSJSONReadingMutableContainers选项生成),我们可以直接修改它的内容:

// 取出list1数组中的第一个元素(你的list1结构是{"list1": [{"innerList": [...]}]})
NSMutableDictionary *firstItem = list1Dict[@"list1"][0];
// 替换innerList为innerList2
firstItem[@"innerList"] = innerList2;

3. (可选)将修改后的集合转回JSON字符串并存回UserDefaults

如果你需要把修改后的结果存回UserDefaults,需要再转成JSON字符串:

NSData *updatedList1Data = [NSJSONSerialization dataWithJSONObject:list1Dict 
                                                           options:0 
                                                             error:&error];
if (error) {
    NSLog(@"生成JSON失败: %@", error.localizedDescription);
    return;
}
NSString *updatedList1JsonStr = [[NSString alloc] initWithData:updatedList1Data 
                                                      encoding:NSUTF8StringEncoding];
[[NSUserDefaults standardUserDefaults] setObject:updatedList1JsonStr forKey:@"list1"];
[[NSUserDefaults standardUserDefaults] synchronize];

关键注意点

  • 始终确认你操作的对象类型:NSUserDefaults里存的如果是JSON,默认是字符串或者已经解析好的集合,一定要先判断类型再操作。
  • 使用NSJSONSerialization进行JSON和Objective-C集合的互转时,记得处理错误,避免崩溃。
  • 如果需要修改集合内容,要生成可变的容器(通过NSJSONReadingMutableContainers选项),不然直接修改不可变字典/数组会导致崩溃。

内容的提问来源于stack exchange,提问作者Earth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 10:43:13