抛出异常为:尝试使用setString改变不可变对象

时间:2014-07-10 11:48:50

标签: ios objective-c xcode nsuserdefaults setstring

我通过[NSUserDefaults standardUserDefaults]将一个数组从一个ViewController传递给另一个。我在第二个视图控制器中检索数组,当我尝试更新字符串值时,它会抛出异常以下

Attempt to mutate immutable object with setString

以下是我的代码。无法追踪问题所在。

  
NSMutableArray *sampleArray = [[NSMutableArray alloc]init];
sampleArray = [[[NSUserDefaults standardUserDefaults]objectForKey:@"commentsArray"] copy];
NSString *commentCount = [NSString stringWithFormat:@"%@",[[sampleArray valueForKey:@"totalComments"]objectAtIndex:Row]];
int cCount = [commentCount intValue];
[[[sampleArray valueForKey:@"totalComments"] objectAtIndex:Row]setString:[NSString stringWithFormat:@"%d",cCount+1]];
  

先谢谢。

4 个答案:

答案 0 :(得分:1)

您的代码:

    NSMutableArray *sampleArray = [[NSMutableArray alloc]init];
    sampleArray = [[[NSUserDefaults standardUserDefaults]objectForKey:@"commentsArray"] copy];
    NSString *commentCount = [NSString stringWithFormat:@"%@",[[sampleArray valueForKey:@"totalComments"]objectAtIndex:Row]];
    int cCount = [commentCount intValue];
    [[[sampleArray valueForKey:@"totalComments"] objectAtIndex:Row]setString:[NSString stringWithFormat:@"%d",cCount+1]];

1)你做

NSMutableArray *sampleArray = [[NSMutableArray alloc]init];
sampleArray = [[[NSUserDefaults standardUserDefaults]objectForKey:@"commentsArray"] copy];

[[NSMutableArray alloc]init]构造一个空的可变数组。随后的sampleArray = [[[NSUserDefaults ... 使用指向不同数组的指针覆盖前一行中设置的指针。这是浪费的动作(并且创建对象很昂贵)。谢天谢地,有ARC,或者它也代表一个泄露的对象。它应该只是

 NSArray *sampleArray = [[NSUserDefaults ...

(注意一个NSMutableArray - 见下文。)

2)你做

sampleArray = [[[NSUserDefaults standardUserDefaults]objectForKey:@"commentsArray"] copy];

最后copy不必要地获取objectForKey返回的对象并复制它。除非这里有可能对原始数组进行不必要的并发修改(在这种情况下这是不可能的),否则这个copy操作完全没有必要,而且操作也很昂贵。

3)你做

NSString *commentCount = [NSString stringWithFormat:@"%@",[[sampleArray valueForKey:@"totalComments"]objectAtIndex:Row]];

简单地(并且昂贵地)执行[NSString stringWithFormat:@"%@",someValue]会创建someValue的副本。同样,这完全没有必要 - 它只会使你的陈述变得更长,更混乱。

4)你做

[[[sampleArray valueForKey:@"totalComments"] objectAtIndex:Row]setString:[NSString stringWithFormat:@"%d",cCount+1]];

让我们将(不必要的)长篇陈述区分开来:

NSArray* temp1 = [sampleArray valueForKey:@"totalComments"];

这是使用"键值"编码并将检查数组中的每个NSDictionary,并询问它是否有任何" totalComments"元件。

NSString* temp2 = [temp1 objectAtIndex:Row];

这会从valueForKey获取结果,并仅检查Row元素。虽然很难在不知道" commentsArray"构造,很可能它(和更清楚地)访问Row的{​​{1}}元素,然后从生成的NSDictionary请求sampleArray值。这本来会更快更清晰。

你现在在temp2中拥有的是一个NSString。你现在有效地执行

totalCommnts

当然,您的问题是NSString现在是不可变的,因此会发生异常。如果要更改它,则必须具有NSMutableString。但你不能简单地安装"自all values returned by NSUserDefaults are immutable以来[temp2 setString:[NSString stringWithFormat:@"%d",cCount+1]]; 数组中的一个,包括temp1sampleArraytemp1。 (并且,不,只需更改声明就不能使它们变得可变。)

所以你有点卡住了。你需要完全重新设计这个功能。

答案 1 :(得分:0)

您的代码行存在问题

sampleArray = [[[NSUserDefaults standardUserDefaults]objectForKey:@"commentsArray"] copy];

因为复制返回非可变数组所以你必须这样做

sampleArray = [NSMutableArray arrayWithArray:[[[NSUserDefaults standardUserDefaults]objectForKey:@"commentsArray"];

答案 2 :(得分:-1)

NSMutableArray *sampleArray = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults]objectForKey:@"commentsArray"]];
NSString *commentCount = [NSString stringWithFormat:@"%@",[[sampleArray valueForKey:@"totalComments"]objectAtIndex:Row]];
int cCount = [commentCount intValue];
NSMutableString *myMutableString = [NSMutableString stringWithString:[[sampleArray valueForKey:@"totalComments"] objectAtIndex:Row]];
[myMutableString setString:[NSString stringWithFormat:@"%d",cCount+1]];

答案 3 :(得分:-1)

问题是你将一个可变数组值传递给一个不可变的字符串。尝试将NSString更改为NSMutableString.Hopefully这有助于