不可变对象收到了可变方法的调用

14

第一次使用此方法时它可以正常工作,但第二次调用时会出现错误“将变异方法发送到不可变对象”。问题在于“addObject”命令所在的行。

-(IBAction) save: (id) sender{

NSMutableArray *placesT= [[NSUserDefaults standardUserDefaults] objectForKey:@"placesT"];

if (!placesT) {
    placesT=[[[NSMutableArray alloc] init] autorelease];
}

[placesT addObject: [NSString stringWithFormat:@"%@", tagF.text] ];

NSUserDefaults *tUD=[NSUserDefaults standardUserDefaults];
[tUD setObject:placesT forKey:@"placesT"];
[tUD synchronize];

[self dismissModalViewControllerAnimated:YES];

}


问题出在placesT的初始化上。我猜NSUserDefault标准在第一次为空,然后进入第二个初始化。你还有一个内存泄漏问题。 - Radu
请注意,您可以将[NSString stringWithFormat:@"%@", tagF.text]替换为仅使用tagF.text。如果text已经是一个NSString,则无需发送+stringWithFormat: - user557219
4个回答

24

正如NSUserDefaults的文档所说:“即使您将可变对象设置为值,从NSUserDefaults返回的值也是不可变的。”每当您想要更改从NSUserDefaults获取的集合时,您必须获取不可变版本,进行mutableCopy,修改它,然后再次设置回来。


2
补充一下,例如:someMutableArray = [yourArrayFromDictionary mutableCopy]; 希望有所帮助 :) - jimbob

10

这是因为存储在NSUserDefaults中的对象不是可变数组,而是普通数组。

- (IBAction)save:(id)sender {

   NSMutableArray *placesT = nil;
   NSArray *tempArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"placesT"];

   if (tempArray) {
      placesT = [tempArray mutableCopy];
   } else {
      placesT = [[NSMutableArray alloc] init];
   }

   [placesT addObject:[NSString stringWithFormat:@"%@", tagF.text]];

   NSUserDefaults *tUD = [NSUserDefaults standardUserDefaults];
   [tUD setObject:placesT forKey:@"placesT"];
   [tUD synchronize];

   [self dismissModalViewControllerAnimated:YES];
   [placesT release];
}

3

placesT 是一个不可变数组,要么总是设置 placesT 为可变对象,要么使用以下代码。

NSMutableArray *placesT= [[[NSUserDefaults standardUserDefaults] objectForKey:@"placesT"] mutableCopy];

0

这应该可以工作:

-(IBAction) save: (id) sender {

NSMutableArray *placesT= [[NSMutableArray alloc]initWithArray:[[NSUserDefaults standardUserDefaults]

objectForKey:@"placesT"]];

if (!placesT) {
    placesT=[[[NSMutableArray alloc] init] autorelease];
}

[placesT addObject: [NSString stringWithFormat:@"%@", tagF.text] ];

NSUserDefaults *tUD=[NSUserDefaults standardUserDefaults];
[tUD setObject:placesT forKey:@"placesT"];
[tUD synchronize];

[self dismissModalViewControllerAnimated:YES]; }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接