insert object in an NSMutableArray saved with NSUserDefaults

JAA picture JAA · Mar 18, 2011 · Viewed 15.4k times · Source

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!

Answer

lxt picture lxt · Mar 18, 2011

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