Objective c NSDictionary的深度可变副本到NSMutableDictionary

Objective c NSDictionary的深度可变副本到NSMutableDictionary,objective-c,ios,nsarray,nsdictionary,Objective C,Ios,Nsarray,Nsdictionary,我有一个属性列表,可以读入NSDictionary,我想从中创建一个可变副本到NSMutableDictionary中以编辑内容,然后通过复制原始内容来重置可变字典 NSDictionary *defaultRows; NSMutableDictionary *rows; NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"]; defaultRows = [[[NSDict

我有一个属性列表,可以读入NSDictionary,我想从中创建一个可变副本到NSMutableDictionary中以编辑内容,然后通过复制原始内容来重置可变字典

NSDictionary *defaultRows;
NSMutableDictionary *rows;

NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"];
defaultRows = [[[NSDictionary alloc] initWithContentsOfFile: plistPath] objectForKey:@"rows"];
这就是我试图创建原始词典副本的方式(根据:

当我尝试使用以下命令更改字典行的内容时:

[[rows-objectForKey:self.company.coaTypeCode]objectForKey:statementType]移除objectsatindex:rowsToDelete];

我收到运行时错误
***由于未捕获的异常“nsinternalinconsistenceexception”而终止应用程序,原因:'-[\u NSCFArray removeObjectAtIndex::]:mutating method sent to immutable object'


我已经读过了,但是想知道是否有一个更优雅的方法来实现一个深层拷贝?

你考虑过使用< /p>吗? NSMutableDictionary *rows = [[[NSMutableDictionary alloc] initWithContentsOfFile:plistPath] objectForKey:@"rows"]; NSMutableDictionary*行=[[[NSMutableDictionary alloc]initWithContentsOfFile:plistPath]objectForKey:@“行”];
由于您正在从属性列表加载
defaultRows
,因此最简单的方法就是使用可变容器反序列化属性列表

NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"];
NSData *rowsData = [NSData dataWithContentsOfFile:plistPath];

NSMutableDictionary *rows = [NSPropertyListSerialization propertyListWithData:rowsData
    options:NSPropertyListMutableContainers format:NULL error:NULL];

如果将defaultRows声明为NSMutableDictionary,是否有效?BryanMac,不幸的是不起作用。我声明了
NSMutableDictionary*rows,*defaultRows;
,但收到了相同的错误消息。如果重新读取属性列表(而不是创建内存中的副本),性能会有什么损失
initWithContentsOfFile:
的文档说明“即使字典是可变的,该字典包含的对象也是不可变的。”@AlexR如果你一直在重读东西,我的假设是,它总是比在内存中保存对象更糟糕。当然,这并不总是可能的,特别是如果你有一个巨大的plist。因此,谨慎的做法可能是创建一批这样的写入,然后一次完成,而不是一步一步地保存它们。另一方面,如果你正在处理使用类似设置视图的工具,只要用户在特定视图中,您就可以始终将对象保存在内存中。我的2美分。这是一种非常酷的方法!但相关选项是否应该是NSPropertyListMutableContainers和Leaves?我的意思是,假设他想编辑NSMutableDictionary中的数组?否则,我会即使是我的答案也能很好地工作:)他问题中的代码试图修改子容器(顶级字典中字典中的数组),因此他需要可变容器。如果他还需要可变叶,他当然可以指定
NSPropertyListMutableContainersAndLeaves
。你的答案行不通,因为它只会创建一个可变的顶级字典;它将子容器创建为不可变的。回答得很好,Rob!非常感谢。顺便问一下,您知道属性列表读取方法是否可以配置为将标准XML文件读入数组和字典?目前,我正在解析XML文件,但希望将它们部分直接读入NSDictionary。
NSPropertyListSerialization
使用特定的XML模式。它不是通用的XML加载器。您将不得不“艰难地”继续这样做(大概是使用
NSXMLParser
)。尽管这有助于op,但这并不是问题的答案。它假定数据来自Plist文件。但是如果我从其他地方得到了这个不可变的NSDictionary,比如说NSUserDefaults,或者仅仅是CoreData实体的一个属性,那会怎么样?我仍然无法将带有键路径的KVC应用于子容器,即使我制作了原始容器的可变副本。如何制作深度可变副本?
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"];
NSData *rowsData = [NSData dataWithContentsOfFile:plistPath];

NSMutableDictionary *rows = [NSPropertyListSerialization propertyListWithData:rowsData
    options:NSPropertyListMutableContainers format:NULL error:NULL];