-2

私を助けてください。

plist clothingList.plist があります

メソッドでこのようにアクセスしています

 NSString *path=[[NSBundle mainBundle] pathForResource:@"ClothingList" ofType:@"plist"];
 //NSDictionary *ClothingAssets ; //Declared globally in .h file

  ClothingAssets=[[NSMutableDictionary alloc]initWithContentsOfFile:path];
 [[NSUserDefaults standardUserDefaults]setObject:ClothingAssets forKey:@"ClothingAssets"];
 [[NSUserDefaults standardUserDefaults] synchronize];

ここで、別の方法で Clothing Assets Dictionary の bool 値を変更したいと考えています。

 ClothingAssets=[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"ClothingAssets"];
 [[[[[[ClothingAssets objectForKey:@"ClothingStore"] objectAtIndex:temp_Store]objectForKey:@"Assets" ]objectForKey:[NSString stringWithFormat:@"%@",temp_AssetType]] objectAtIndex:ii] setValue:@"YES" forKey:@"isLock"] ;

コードを初めて実行するとクラッシュし、次のようなエラーが表示されます。

************ Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'***
 *** First throw call stack:
 (0x1fb5012 0x29c5e7e 0x1fb4deb 0x1f7b347 0x3f39bf 0x435d9 0x41f76 0xea5020 0x29d9705 0xab5920 0xab58b8 0xb76671 0xb76bcf 0xb75d38 0xae533f 0xae5552 0xac33aa 0xab4cf8 0x3397df9 0x3397ad0 0x1f2abf5 0x1f2a962 0x1f5bbb6 0x1f5af44 0x1f5ae1b 0x33967e3 0x3396668 0xab265c 0x22ed 0x2225 0x1)
 libc++abi.dylib: terminate called throwing an exception******

しかし、コードを 2 回目に実行すると、正しく動作しています。

私を助けてください。

4

2 に答える 2

2

似たような質問がたくさんあります。例外から、不変の辞書に値を含めようとしていることは明らかです。

一度に 1 つずつ値をアンラップし、それらを編集するので、常に mutableCopy を作成します。

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

NSMutableDictionary *clothingAssets=[[defaults dictionaryForKey:@"ClothingAssets"] mutableCopy];

NSMutableArray *clothingStores      = [clothingAssets[@"ClothingStore"] mutableCopy];
NSMutableDictionary *clothingStore  = [clothingStores[temp_Store] mutableCopy];

NSMutableDictionary *assets         = [clothingStore[@"Assets"]mutableCopy];

NSString *assetTypesKey             = [NSString stringWithFormat:@"%@",temp_AssetType];
NSMutableArray *assetTypes          = [assets[assetTypesKey]mutableCopy];
NSMutableDictionary *assetType      = [assetTypes[i] mutableCopy];

//Value is set
assetType[@"isLock"] = @"YES";

//Now you need to update the values back to the top most level
[assetTypes replaceObjectAtIndex:i withObject:assetType];
assets[assetTypesKey] = assetTypes ;
clothingStore[@"Assets"] = assets;
[clothingStores replaceObjectAtIndex:temp_Store withObject:clothingStore];
clothingAssets[@"ClothingStore"] = clothingStores;

[defaults setObject:clothingAssets forKey:@"ClothingAssets"];
[defaults synchronize];
于 2013-06-12T09:00:51.617 に答える
0

ネストされたメッセージの送信はさておき、これは実際にはかなり簡単です。このエラーが表示された場合は、不変オブジェクトを変更しようとしていることを意味します。それを行おうとすると、ランタイムは癇癪を起こします。代わりに、次のようにします。

ClothingAssets=[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"ClothingAssets"];
NSDictionary *clothingStore = [ClothingAssets objectForKey:@"ClothingStore"];
NSArray *assets = [clothingStore objectForKey:@"Assets"];
NSDictionary *subAsset = [assets objectAtIndex: temp_Store];
NSArray *subAssetArray = [subAsset objectForKey: [NSString stringWithFormat:@"%@",temp_AssetType];

// At this point I'm afraid I run out of creative ways to describe your storage hierarchy:
NSDictionary *subAssetArraySubDictionary = [subAssetArray objectAtIndex: ii];
NSMutableDictionary *mutableCopy = [subAssetArraySubDictionary mutableCopy];

// And finally, set the value:
// Beware: This uses the string YES instead of a boolean value for YES - you need to remember this
// when accessing it later.
[mutableCopy setValue: @"YES" forKey: @"isLock"];
于 2013-06-12T08:47:58.073 に答える