2013-06-12 49 views
-2

請幫幫我。在運行時修改NSDictionary

我有一個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]; 

現在我想在另一種方法來modfify在服裝資產字典一個布爾值,訪問它這樣。

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****** 

但是當我運行它正常工作第二次的代碼。

請幫幫我。

+3

啊呀6'['在一個語句;很高興。你認爲這很容易理解嗎? – trojanfoe

回答

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"]; 
2

有很多類似的問題。從例外中可以看出,你試圖將一個值包含在一個不可變的字典中。

展開值一次一個因爲你要編輯它們總是會讓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]; 
+0

mutableCopy的確是這裏的關鍵答案。這是一個標準的plist陷阱。 – uchuugaka