これはかなり一般的な問題のようですが、私が調べた解決策ではエラーは解決されません。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];
}
}