错误:突变方法从JSON文件发送到不可变对象的NSMutableArray(Error: Mutat

2019-06-26 08:36发布

这似乎是一个相当普遍的问题,但我已经看了解决方案并没有解决错误。 我想从一个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'

我的财产定义为我的实现文件的顶部如下:

NSMutableArray *inventoryData;

我想如下从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"]];
    }
}

那么我想这里看到的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];
    }
}

Answer 1:

这个问题似乎是围绕在您工作......你只创建容器的可变版本适用于“级别”的深度。 您稍后索引到该水平(即访问容器更深一层),这仍然是不变的。 尝试传递NSJSONReadingMutableContainers选项,当您第一次反序列化JSON:

NSUInteger jsonReadingOptions = NSJSONReadingAllowFragments | NSJSONReadingMutableContainers;
NSMutableDictionary *localDictionary = [[NSMutableDictionary alloc] initWithDictionary:[NSJSONSerialization JSONObjectWithData:RawJSON options:jsonReadinOptions error:&e]];


文章来源: Error: Mutating method sent to immutable object for NSMutableArray from JSON file