iOS开发:如何将嵌套TreeNode对象数组保存为本地JSON文件
解决自定义嵌套TreeNode数组转JSON并保存的问题
问题原因
**NSJSONSerialization**仅支持序列化Foundation框架的基础类型(如NSString、NSNumber、NSArray、NSDictionary、NSNull),自定义的TreeNode对象不属于这些支持类型,直接传入序列化方法会失败。
解决方案:将TreeNode递归转为字典数组
给TreeNode类添加方法,把自身转为符合JSON结构的字典,同时递归处理嵌套的children数组,最后将整个TreeNode数组转为字典数组,再进行JSON序列化。
步骤1:扩展TreeNode类,添加转字典方法
在TreeNode.h中添加方法声明:
- (NSDictionary *)toDictionary;
在TreeNode.m中实现该方法:
- (NSDictionary *)toDictionary { // 递归处理children数组,转为字典数组 NSMutableArray *childrenDicts = [NSMutableArray array]; for (TreeNode *child in self.children) { [childrenDicts addObject:[child toDictionary]]; } // 组装当前节点的字典,nil值替换为NSNull避免序列化失败 return @{ @"title": self.title ?: [NSNull null], @"identifier": self.identifier ?: [NSNull null], @"isCompleted": @(self.isCompleted), @"children": childrenDicts }; }
步骤2:将TreeNode数组转为字典数组并序列化保存
假设你有一个NSArray<TreeNode *> *treeNodes,执行以下代码完成序列化并保存到本地文档目录:
// 1. 将TreeNode数组转为字典数组 NSMutableArray *dictArray = [NSMutableArray array]; for (TreeNode *node in treeNodes) { [dictArray addObject:[node toDictionary]]; } // 2. 序列化为JSON数据 NSError *error = nil; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictArray options:NSJSONWritingPrettyPrinted // 格式化输出,可选 error:&error]; if (error) { NSLog(@"JSON序列化失败:%@", error.localizedDescription); return; } // 3. 获取本地文档目录路径 NSString *documentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *jsonPath = [documentsDir stringByAppendingPathComponent:@"treeData.json"]; // 4. 写入文件 BOOL success = [jsonData writeToFile:jsonPath atomically:YES]; if (success) { NSLog(@"JSON文件保存成功:%@", jsonPath); } else { NSLog(@"JSON文件保存失败"); }
额外:从JSON文件恢复TreeNode数组
如果需要反向解析,可在TreeNode类中添加递归解析的类方法:
// 在TreeNode.h中声明 + (TreeNode *)nodeFromDictionary:(NSDictionary *)dict; // 在TreeNode.m中实现 + (TreeNode *)nodeFromDictionary:(NSDictionary *)dict { NSString *title = dict[@"title"]; if ([title isKindOfClass:[NSNull class]]) title = nil; NSString *identifier = dict[@"identifier"]; if ([identifier isKindOfClass:[NSNull class]]) identifier = nil; TreeNode *node = [[TreeNode alloc] initWithValue:title :identifier]; node.isCompleted = [dict[@"isCompleted"] boolValue]; // 递归解析children NSArray *childrenDicts = dict[@"children"]; for (NSDictionary *childDict in childrenDicts) { TreeNode *child = [TreeNode nodeFromDictionary:childDict]; [node addChild:child]; } return node; } // 恢复数组的调用代码 NSData *savedData = [NSData dataWithContentsOfFile:jsonPath]; if (savedData) { NSError *parseError = nil; NSArray *savedDicts = [NSJSONSerialization JSONObjectWithData:savedData options:0 error:&parseError]; if (!parseError) { NSMutableArray *restoredNodes = [NSMutableArray array]; for (NSDictionary *dict in savedDicts) { [restoredNodes addObject:[TreeNode nodeFromDictionary:dict]]; } // restoredNodes即为恢复后的TreeNode数组 } }
内容的提问来源于stack exchange,提问作者mars_dev
相关产品推荐
相关产品推荐

