Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding new object to retrieved NSMutableArray - returns NSInternalInconsistencyException

I keep getting this error when I try to add an object to a retrieved NSMutableArray.

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'

Retrieve:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    NSMutableArray *arrayOfTitles = [userDefaults objectForKey:@"mainArraySaveData"];
    NSMutableArray *arrayOfSubjects = [userDefaults objectForKey:@"subjectArraySaveData"];
    NSMutableArray *arrayOfDates = [userDefaults objectForKey:@"dateArraySaveData"];

    _mutableArray=arrayOfTitles;
    _subjectArray=arrayOfSubjects;
    _dateArray=arrayOfDates;

    [_tableView reloadData];

Save:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
_mutableArray = [[NSMutableArray alloc] initWithArray:[userDefaults objectForKey:@"mainArraySaveData"]];
[userDefaults setObject:_mutableArray forKey:@"mainArraySaveData"];
[userDefaults synchronize];

_dateArray = [[NSMutableArray alloc] initWithArray: [userDefaults objectForKey:@"dateArraySaveData"]];
[userDefaults setObject:_dateArray forKey:@"dateArraySaveData"];
[userDefaults synchronize];

_subjectArray = [[NSMutableArray alloc] initWithArray: [userDefaults objectForKey:@"subjectArraySaveData"]];
[userDefaults setObject:_subjectArray forKey:@"subjectArraySaveData"];
[userDefaults synchronize];

I'm confused as I thought this was designed to return an NSMutableArray, but it says not - NSArray. What's my issue?? Thanks, SebOH

like image 326
Seb OH Avatar asked Mar 01 '14 11:03

Seb OH


2 Answers

I'm confused as I thought this was designed to return an NSMutableArray, but it says not - NSArray. What's my issue?

The documentation of the NSUserDefaults talks specifically about this issue in the "special considerations" section of the objectForKey: method:

Special Considerations

The returned object is immutable, even if the value you originally set was mutable.

Fixing this problem is easy - use mutableCopy:, initWithArray: or arrayWithArray: method to make mutable copies:

_mutableArray=[arrayOfTitles mutableCopy];                      // You can do this...
_subjectArray=[NSMutableArray arrayWithArray:arrayOfSubjects];  // ...or this
_dateArray=[[NSMutableArray alloc] initWithArray:arrayOfDates]; // ...or this.
like image 143
Sergey Kalinichenko Avatar answered Oct 22 '22 23:10

Sergey Kalinichenko


User defaults returns immutable objects so you need to call mutableCopy on each before you can modify them.

When you define a variable as NSMutableArray * it is your responsibility to ensure that the instance you store there is of the correct type. The compiler will only tell you that you're wrong if it can tell. In this case the method returns id as you are requesting 'whatever object type exists for this key' from user defaults.

like image 38
Wain Avatar answered Oct 22 '22 23:10

Wain