Getting “mutating method sent to immutable object”

2019-01-20 16:42发布

I can't figure out what is causing this. Basically, a few different 'tasks' are colliding with each other in my app. When i press a button, it runs this code just fine:

PalAppDelegate *dataCenter = (PalAppDelegate *)[[UIApplication sharedApplication] delegate];




[dataCenter.colourPalettesContainer addObject:[NSNumber numberWithInt:5]];

It can do this as many times as i like. But when i perform another task (and theres a few which cause this to happen), which involves this code for example:

PalAppDelegate *dataCenter = (PalAppDelegate *)[[UIApplication sharedApplication] delegate];

[dataCenter.colourPalettesContainer removeObjectAtIndex:touchDownID];

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:dataCenter.colourPalettesContainer forKey:@"container"];
[prefs synchronize];

and then:

dataCenter.colourPalettesContainer = [prefs objectForKey:@"container"];

When i run the first code again after this, it causes a crash with the "mutating method sent to immutable object" error. How can i stop this?

EDIT: So i've found out the problem from some answers below. Does anybody have a different method of doing this which they'd suggest?

3条回答
我只想做你的唯一
2楼-- · 2019-01-20 17:38

NSUserDefaults always returns immutable objects, even if what you stored was mutable. To work around this, you need to make a mutable copy. Since -mutableCopy returns an object that the caller owns, it needs to be (auto)released:

dataCenter.colourPalettesContainer = [[[prefs objectForKey:@"container"] mutableCopy] autorelease];

(Edit) I posted some -mutableDeepCopy NSArray & NSDictionary methods a while back, in response to another question. If your problem involves deeper nesting of collections, and you need them all to be mutable, this may help.

查看更多
贼婆χ
3楼-- · 2019-01-20 17:39

NSUserDefaults returns an immutable array. You need to make a mutable copy of it when you load it back up:

NSMutableArray *mutableArray = [[prefs objectForKey:@"container"] mutableCopy];
dataCenter.colourPalettesContainer = mutableArray;
[mutableArray release];

You might also have to do some manipulation inside of the array since you were storing NSMutableArrays within it.

查看更多
时光不老,我们不散
4楼-- · 2019-01-20 17:43

TO REMOVE AN OBJECT FROM PARTICULAR INDEX OF AN ARRAY. (Swift 3.0)

let fullArray : NSArray = Userdefaults().value(forKey: "YOUR_ARRAY_STRING") as! NSArray
var mutableArray : [AnyObject] = fullArray as [AnyObject]
mutableArray.remove(at: INDEX_TO_REMOVE) //Eg: mutableArray.remove(at: 0)
mutableArray.append(ARRAY_TO_APPEND)
查看更多
登录 后发表回答