2011-12-04 48 views
1

我有一個iPhone應用程序,從服務器拉一些JSON數據,然後將其解析成包含子數組和子字典的字典數組。如何深度複製NSDictionaries的NSArray?

現在,我已經存儲在一個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" } 
     ]}, 

當我刪除不再需要我不能恢復元件的模塊。

那麼無論如何要做一個完整的副本,包括所有的子對象?

回答

2

你可以保留原始的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]; 
+0

我去了第一個選項。我嘗試了第二個,但是我的應用程序崩潰了。 – Ash

1

我建議爲你的字典所代表的任何東西做一個模型對象。讓你的課堂能夠從字典中創建一個對象,並且這些對象能夠正確地複製它們自己。您可以爲時間表,事件或兩者兼而有之。然後您可以使用initWithArray:copyItems:複製時間表或事件數組。

作爲獎勵,使用真正的模型對象而不是字典將使您的代碼更清潔。

現在我已經存儲在伊娃時間了,然後將它複製到filteredTimetable之前,通過filteredTimetable循環並移除我不需要的對象。

甚至可以使用核心數據使模型對象管理對象。然後,您可以使用獲取請求進行過濾,並根據您正在做的事情,您可以使用NSFetchedResultsController讓Core Data爲您做更多工作。

2

就像今天(iOS7,它存在於iOS5上)一樣,即使在複雜結構(數組在字典內部,數組內部等等)中深度複製Foundation對象(NSDictionary,NSArray,NSString,NSNumber ...) on ...)是使用JSON序列化。

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

如果需要,還可以更改反序列化的選項以獲取不可變副本。