NSMutableArray removeAllObjects导致崩溃

时间:2013-02-12 14:25:00

标签: ios exception ios6 nsmutablearray

我的NSMutableArray中有一个ViewController,这是UITableView定义的数据源,如下所示:

NSMutableArray *messageArray;

我有一个方法来重新加载tableView数据,在此之前,我想清除现有的表数据。

如果我使用以下代码:

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

我得到以下异常:

  

2013-02-12 14:20:30.378 appname [20998:907] *终止应用程序   未捕获的异常'NSInternalInconsistencyException',原因:   ' - [__ NSCFArray removeObjectAtIndex:]:发送变异方法   不可变对象'   * 第一次抛出调用堆栈:(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调用抛出异常

但如果我使用以下代码,它就可以了。

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

为什么我收到removeAllObjects的错误? 这可能是罪魁祸首吗?

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

6 个答案:

答案 0 :(得分:5)

  

这可能是罪魁祸首吗?

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

是的,您想要使用可变容器的选项:

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

答案 1 :(得分:2)

看起来你的“NSMutableArray”实际上是NSArray强制转换为NSMutableArray。

在代码中搜索以下内容:

messageArray = (NSMutableArray *)[obj methodReturningNSArray];

removeAllObjects仅适用于真正的NSMutableArray,因为错误“发送到不可变对象的变异方法”状态。

答案 2 :(得分:1)

你必须改变这一行:

messageArray = responseDictionary[@"data"];

为:

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

默认情况下,从字典中获取的对象是不可变的

答案 3 :(得分:0)

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

答案 4 :(得分:0)

如何找到错误的地点:

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

答案 5 :(得分:0)

您已将NSMutableArray设置为NSArray的实例,而不是NSMutableArray或您将NSMutableArray声明为NSArray vs. NSMutableArray类型的属性。

Cocoa文档使用immutable一词来引用只读无法更改后的初始化对象

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

您可以在copyWithZone referenceNSMutableCopying protocol reference中找到更多详细信息。