问题
I have an NSMutableArray saved with NSUserDefaults. This array is my "favourite" items that the user can saves, so when i want to add one item, i need to read the array (from NSuserDefault) and save in the first free position.
I'm using this method to add a value in the NSMutableArray
-(IBAction)save{
NSMutableArray *abc = [[NSUserDefaults standardUserDefaults] objectForKey:@"12345"];
int n = [abc count];
[abc insertObject:@"aaa" atIndex:n];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[[NSUserDefaults standardUserDefaults] setObject:abc forKey:@"12345"];
[defaults synchronize];
[abc release];
}
what's the deal? That if the user call this method two times, the second time the app crashes with this log:
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'
why? and why just the second time? The first time works fine!
回答1:
NSUserDefaults
always returns immutable objects, even if the original object was mutable. It's in the documentation for objectForKey
:
The returned object is immutable, even if the value you originally set was mutable.
You will need to create a copy of the returned object before you modify it, using [NSMutableArray arrayWithArray:]
Probably also best to use the arrayForKey
method of NSUserDefaults
if you're retrieving an array. Docs here: https://developer.apple.com/documentation/foundation/userdefaults
回答2:
Here is a complete working example:
- (void)saveScore:(NSNumber *)score
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *scoreList = [[NSMutableArray alloc] initWithArray: [defaults objectForKey:@"ScoreList"]];
[scoreList addObject:score];
[defaults setObject:scoreList forKey:@"ScoreList"];
[defaults synchronize];
}
First we read in the stored data in a mutable array, update the array, save the new array, and then synchronize the user defaults to permanently record the changes.
Hope this helps!
回答3:
Another option is:
[[NSUserDefaults standardUserDefaults] setObject:[[[NSUserDefaults standardUserDefaults] objectForKey:@"12345"] arrayByAddingObject:object] forKey:@"12345"];
回答4:
Copy Array from an NSUserDefault
like this way :
[YourArray addObjectsFromArray:[[NSUserDefaults standardUserDefaults]
objectForKey:@"NSUSD"]];
or
YourArray = [[NSMutableArray alloc]
initWithArray:[[NSUserDefaults standardUserDefaults]
objectForKey:@"NSUSD"]];
[YourArray addObject: (currentObject)];
回答5:
It is because you NSMutablepointer points an NSUserDefault object directly. You should first copy NSUserDefault object to an array than process it.
NSMutableArray *arr= [NSMutableArray arrayWithObjects:@"asd",@"dsa",nil];
[[NSUserDefaults standardUserDefaults] setObject:arr forKey:@"12345"];
NSMutableArray *abc = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"12345"]];
//[[NSUserDefaults standardUserDefaults] objectForKey:@"12345"];
int n = [abc count];
[abc insertObject:@"aaa" atIndex:n];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[[NSUserDefaults standardUserDefaults] setObject:abc forKey:@"12345"];
[defaults synchronize];
[abc release];
回答6:
Quick fix:
_retrivedArray = [_mutableArray mutableCopy];
来源:https://stackoverflow.com/questions/5346395/insert-object-in-an-nsmutablearray-saved-with-nsuserdefaults