错误:从JSON文件发送到NSMutableArray的不可变对象的Mutating方法

Val*_*ine 3 xcode objective-c popup viewdidload

这似乎是一个相当普遍的问题,但我所看到的解决方案并没有解决错误.我试图从JSON文件中读取NSMutableArray.我见过的许多建议涉及使用mutableCopy[NSMutableArray arrayWithArray:],但这两个解决方案在使用调用replaceObjectAtIndex:withObject时都没有解决问题:见下文.如果您对如何解决此问题有任何建议,请告诉我.

编辑:我还想补充说,库存清单是NSMutableArray对象的NSMutableArray.

确切的错误如下:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', 
reason: '-[__NSCFArray replaceObjectAtIndex:withObject:]: 
mutating method sent to immutable object'
Run Code Online (Sandbox Code Playgroud)

我在我的实现文件的顶部定义了如下属性:

NSMutableArray *inventoryData;
Run Code Online (Sandbox Code Playgroud)

我试图从JSON文件中读取它,如下所示:

- (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"]];
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我尝试替换NSMutableArray的给定索引处的对象,如下所示:

- (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];
    }
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*hey 7

问题似乎围绕着您工作的深度......您正在创建的容器的可变版本仅适用于该"级别".您稍后将索引到该级别(即访问更深层次的容器),这仍然是不可变的.NSJSONReadingMutableContainers首次反序列化JSON时尝试传递该选项:

NSUInteger jsonReadingOptions = NSJSONReadingAllowFragments | NSJSONReadingMutableContainers;
NSMutableDictionary *localDictionary = [[NSMutableDictionary alloc] initWithDictionary:[NSJSONSerialization JSONObjectWithData:RawJSON options:jsonReadinOptions error:&e]];
Run Code Online (Sandbox Code Playgroud)