问题描述
这似乎是一个相当普遍的问题,但我查看的解决方案并不能解决该错误.我正在尝试从 JSON 文件中读取 NSMutableArray.我看到的许多建议涉及使用 mutableCopy 或 [NSMutableArray arrayWithArray:] 但这两种解决方案都不能解决使用调用 replaceObjectAtIndex:withObject 时的问题: 见下文.如果您对如何解决此问题有任何建议,请告诉我.
This seems to be a fairly common problem, but the solutions that I have looked at do not solve the error. I am trying to read an NSMutableArray from a JSON file. Many of the suggestions I have seen involve using mutableCopy or [NSMutableArray arrayWithArray:] but both of these solutions do not fix the problem when using the call replaceObjectAtIndex:withObject: seen below. Please let me know if you have any advice on how to solve this problem.
我还想补充一点,清单列表是 NSMutableArray 对象的 NSMutableArray.
I would also like to add that the inventory list is an NSMutableArray of NSMutableArray objects.
确切的错误是:
Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: '-[__NSCFArray replaceObjectAtIndex:withObject:]:
mutating method sent to immutable object'
我在实现文件的顶部定义了如下属性:
I have the property defined as follows at the top of my implementation file:
NSMutableArray *inventoryData;
我正在尝试从 JSON 文件中读取它,如下所示:
I am trying to read it from a JSON file as follows:
- (void)readJSON
{
//Code to get dictionary full of saves from JSON file (overworld.json) - includes the file path on the ipad as well as
//the dictionary itself
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *localPath = [[NSString alloc] initWithString:[documentsDirectory stringByAppendingPathComponent:@"savedPaintGameData.json"]];
NSString *filePath = [localPath mutableCopy];
NSError *e = nil;
// Read data from file saved previously - read the raw data from the path, then parse it into a dictionary using JSONObjectWithData
NSData *RawJSON = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&e];
if (RawJSON == nil) {
[self saveGameInitialize];
} else {
NSMutableDictionary *localDictionary = [[NSMutableDictionary alloc] initWithDictionary:[NSJSONSerialization JSONObjectWithData:RawJSON options:NSJSONReadingAllowFragments error:&e]];
NSMutableDictionary *savedDataDictionary = [localDictionary mutableCopy];
//inventoryData = [[savedDataDictionary objectForKey:@"inventory"] mutableCopy];
inventoryData = [NSMutableArray arrayWithArray:[savedDataDictionary objectForKey:@"inventory"]];
}
}
然后我尝试替换 NSMutableArray 的给定索引处的对象,如下所示:
I am then trying to replace an object at the given index of the NSMutableArray as seen here:
- (void)setInventoryData: (NSString *) colorKey: (int) change
{
// Check if inventory already contains the paint and change the amount
bool foundPaint = false;
int newAmount = 100; // Magic number prevents crashing @ removal check
for (int i = 0; i < [inventoryData count]; i++) {
NSMutableArray *object = [inventoryData objectAtIndex:i];
if ([[object objectAtIndex:0] isEqualToString:colorKey]) {
newAmount = [[object objectAtIndex:1] integerValue] + change;
[[inventoryData objectAtIndex:i] replaceObjectAtIndex:1 withObject:[NSNumber numberWithInt:newAmount]];
foundPaint = true;
break;
}
}
if (newAmount == 0) {
[self removeInventoryColor:colorKey];
}
}
推荐答案
问题似乎与您工作的深度有关...您正在创建的容器的可变版本仅适用于该级别".您稍后将索引到该级别(即访问更深一层的容器),该级别仍然是不可变的.首次反序列化 JSON 时尝试传递 NSJSONReadingMutableContainers
选项:
The issue appears to be surround the depth at which you are working... the mutable versions of containers you are creating only apply to that "level". You are later indexing into that level (i.e. accessing a container one level deeper) which is still immutable. Try passing the NSJSONReadingMutableContainers
option when you first unserialize the JSON:
NSUInteger jsonReadingOptions = NSJSONReadingAllowFragments | NSJSONReadingMutableContainers;
NSMutableDictionary *localDictionary = [[NSMutableDictionary alloc] initWithDictionary:[NSJSONSerialization JSONObjectWithData:RawJSON options:jsonReadinOptions error:&e]];
这篇关于错误:从 JSON 文件发送到 NSMutableArray 的不可变对象的变异方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!