insert object in an NSMutableArray saved with NSUserDefaults

坚强是说给别人听的谎言 提交于 2019-11-26 17:10:11

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!