2013-02-12 103 views
2

我在ViewControllerNSMutableArray是像这样定义我UITableView数据源:的NSMutableArray removeAllObjects导致崩溃

NSMutableArray *messageArray; 

我必须重新加载的tableView数据的方法,之前它,我想清除现有的表格数据。

如果我使用下面的代码:

[messageArray removeAllObjects];  
    [self.tableView reloadData]; 

我得到以下异常:

2013-02-12 14:20:30.378 appname[20998:907] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object' * First throw call stack: (0x3939e3e7 0x35dd6963 0x3939e307 0x393200e7 0x392eb5e5 0x7cda3 0x3a236047 0x3a2360d1 0x3a236047 0x3a235ffb 0x3a235fd5 0x3a23588b 0x3a235d79 0x3a15e5c9 0x3a14b8b1 0x3a14b1bf 0x336305f7 0x33630227 0x393733e7 0x3937338b 0x3937220f 0x392e523d 0x392e50c9 0x3362f33b 0x3a19f291 0x79c11 0x39be4b20) libc++abi.dylib: terminate called throwing an exception

但是,如果使用下面的代码,它的工作原理。

NSMutableArray *emptyArray = [NSMutableArray new]; 
    messageArray = emptyArray;  
    [self.tableView reloadData]; 

为什么我得到一个错误​​? 这可能是罪魁祸首吗?

NSMutableDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil]; 
    messageArray = responseDictionary[@"data"]; 
+1

这是相关的? http://stackoverflow.com/questions/5707360/why-am-i-getting-mutating-method-sent-to-immutable-object-when-trying-remove – trojanfoe 2013-02-12 14:27:33

+0

你在哪里分配messageArray?你在哪里填充它(即,当你移除所有的对象时,它里面有什么对象)? – thegrinner 2013-02-12 14:27:50

回答

5

Could this be the culprit?

NSMutableDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil]; 
messageArray = responseDictionary[@"data"]; 

是的,你要使用可变容器的选择:

NSMutableDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData options: NSJSONReadingMutableContainers error:NULL]; 
2

它看起来像你的“NSMutableArray”实际上是一个NSArray转换为NSMutableArray。

搜索你这样的事情代码:

messageArray = (NSMutableArray *)[obj methodReturningNSArray]; 

​​只会在真正的NSMutableArray工作,因为错误状态“发送到不可变对象变异方法”。

+0

我没有类似的东西,但我认为它是以某种方式投射到NSArray – conorgriffin 2013-02-12 14:28:20

+0

默认情况下,JSON创建NSArray的非NSMutableArrays的,所以你的猜测是正确的。在数组中使用mutableCopy作为tkanzakic显示是一种解决方案,即messageArray = [responseDictionary [@“data”] mutableCopy]; – Brane 2013-02-12 14:39:28

0

您的数据重新加载返回的messageArray不是NSMutableArray,而是NSArray。如果您在重新加载后停止调试器,您可以验证这一点。设置messageArray时使用.mutableCopy

1

你有可能改变这一行:

messageArray = responseDictionary[@"data"]; 

到:

messageArray = [responseDictionary[@"data"] mutableCopy]; 

默认情况下,你从字典中获取的对象都是非mutables

+1

不,从字典中获得的对象是之前放入它的对象。如果反序列化取决于desirialization代码。例如'NSPropertyListSerialization'支持两者。 – 2013-02-12 14:37:27

+0

是的,你是对的,我真的是指'NSJSONSerialization',除非你指定你对可变拷贝感兴趣 – tkanzakic 2013-02-12 14:40:46

+0

啊,我明白了。对不起,听起来活泼。 – 2013-02-12 14:41:33

0

如何找到点与错误:

  1. 检查是否你@合成一个名为messageArray的属性。如果此属性为NSArray类型或用copy修饰符声明,则合成的setter是罪魁祸首。
  2. 如果不是,则重新声明ivar NSMutableArray *const messageArray。现在编译器会向你显示每个任务。检查NSArray的分配。之后不要忘记恢复声明。
  3. 完成后,将ivar重命名为_messageArray,以便在将来更快地找到直接访问。
0

某处你已设置NSMutableArrayNSArray,不NSMutableArray实例,也宣告NSMutableArray作为NSArray vs. NSMutableArray类型的属性。

Cocoa文档使用字immutable不可阻挡的要改变的,后初始化对象只读。

此外,您应遵循Cocoa/Objective-C命名约定。即,班级名称以大写开头;变量采用形式myArray(或更具描述性的内容,最好是)。

您可以在copyWithZone referenceNSMutableCopying protocol reference中找到更多的细节。