获取“变异方法发送到不可变对象”错误

时间:2011-04-19 01:34:48

标签: iphone objective-c nsmutablearray

我无法弄清楚造成这种情况的原因。基本上,一些不同的“任务”在我的应用程序中相互冲突。当我按下按钮时,它运行此代码就好了:

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




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

它可以像我喜欢的那样多次这样做。但是,当我执行另一项任务时(还有一些会导致这种情况发生),这涉及到以下代码:

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

[dataCenter.colourPalettesContainer removeObjectAtIndex:touchDownID];

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

然后:

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

当我在此之后再次运行第一个代码时,它会导致“发送到不可变对象的变异方法”错误。我怎么能阻止这个?

编辑:所以我从下面的一些答案中找到了问题。是否有人采用不同的方法来做这个建议?

3 个答案:

答案 0 :(得分:6)

NSUserDefaults返回一个不可变数组。当你加载它时,你需要制作一个可变的副本:

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

您可能还需要在数组内部进行一些操作,因为您在其中存储了NSMutableArrays。

答案 1 :(得分:2)

NSUserDefaults总是返回不可变对象,即使您存储的内容是可变的。要解决此问题,您需要制作一个可变副本。由于-mutableCopy返回调用者拥有的对象,因此需要(自动)释放:

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

编辑)我回复了一些-mutableDeepCopy NSArray & NSDictionary methods,以回应另一个问题。如果您的问题涉及集合的更深层嵌套,并且您需要它们 all 是可变的,这可能会有所帮助。

答案 2 :(得分:0)

从阵列的特定索引中删除对象。 (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)