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
相关产品推荐
相关产品推荐

