如何深度复制nsdictionary的NSArray



我有一个iPhone应用程序,它从服务器提取一些JSON数据,然后将其解析为包含子数组和子字典的字典数组。

现在我已经将其存储在ivar timeTable中,然后将其复制到filteredTimetable,然后循环filteredTimetable并删除我不需要的对象。

我遇到的问题是当我尝试恢复数组时,它可以再次被过滤。之前从复制的NSArray中移除的对象也会从原始的NSArray中移除。

filteredTimeTable = [[NSMutableArray alloc] initWithArray:timeTable copyItems:YES];

我认为这是因为filteredTimeTable只是在timeTable中存储指向对象的指针,而不是复制内存。

下面是我的数据结构的一个例子:

    [
        {"time":"09:00",
        "events": [
            { "module":"COMP319", "type":"lecture", "room":"BROD-108:80" }
            { "module":"COMP320", "type":"lab", "room":"BROD-LT" }
        ]},

当我删除一个不再需要的模块时,我不能恢复该元素。

那么是否有办法做一个包含所有子对象的完整复制呢?

你可以保留原来的JSON字符串,然后重新解析它。

如果你出于某种原因不想那样做,如果它都是有效的属性列表对象(NSArray, NSDictionary, NSString, NSNumber, NSDate, NSData)最简单的方法是使用属性列表序列化:

NSData *archive = [NSPropertyListSerialization dataWithPropertyList:originalObject format:NSPropertyListBinaryFormat_v1_0 options:0 error:NULL];
NSMutableArray *copiedObject = [NSPropertyListSerialization propertyListWithData:archive options:NSPropertyListMutableContainers format:NULL error:NULL];

今天(iOS7,从iOS5开始存在),即使在复杂的结构中(数组在字典中,数组在数组中等等),深度复制基础对象(NSDictionary, NSArray, NSString, NSNumber…)的最快方法是使用JSON序列化。

NSData *buffer = [NSJSONSerialization dataWithJSONObject:srcObject options:0 error:nil];
id mutableDeepCopiedObject = [NSJSONSerialization JSONObjectWithData:buffer options:NSJSONReadingMutableContainers+NSJSONReadingMutableLeaves error:nil];

如果需要,您还可以更改反序列化选项以获得不可变副本。

我建议为您的字典所表示的内容创建一个模型对象。使您的类能够从字典中创建对象,并且这些对象能够正确地复制自己。您可以对时间表、事件或两者都这样做。然后,您可以使用initWithArray:copyItems:来复制一个时间表或事件数组。

作为奖励,使用真正的模型对象而不是字典将使您的代码更清晰。

现在我已经将它存储在一个ivar timetable中,然后将其复制到filtered时间表,然后循环通过filtered时间表并删除我不需要的对象。

您甚至可以使用Core Data使模型对象管理对象。然后你可以使用取回请求来做过滤,取决于你在做什么,你可能能够使用NSFetchedResultsController让Core Data为你做更多

最新更新