将对象添加到导致崩溃的NSMutableArray

问题描述:

我正在创建一个以CGRect(屏幕大小)开头的应用程序。当用户触及CGRect时,它被切割成两个CGRect。当我触及创建的新CGRect的内部时,我可以很好地工作,但是当我在CGRect中触摸不是添加到矩形阵列中的最新CGRect时,应用程序崩溃并说sigabrt。将对象添加到导致崩溃的NSMutableArray

这里是的touchesBegan代码,blockPoint是当屏幕被触摸

for (NSValue *val in rectangleArray){ 
    CGRect rectangle = [val CGRectValue]; 
    if (CGRectContainsPoint(rectangle, blockPoint)) { 
     CGRect newRectangle; 
     CGRect addRectangle; 
     if (!inLandscape) { 
      newRectangle = CGRectMake(rectangle.origin.x, rectangle.origin.y, rectangle.size.width, blockPoint.y - rectangle.origin.y); 
      addRectangle = CGRectMake(rectangle.origin.x, blockPoint.y, rectangle.size.width, rectangle.size.height - (blockPoint.y - rectangle.origin.y)); 

     } 
     else { 
      newRectangle = CGRectMake(rectangle.origin.x, rectangle.origin.y, blockPoint.x - rectangle.origin.x, rectangle.size.height); 
      addRectangle = CGRectMake(blockPoint.x, rectangle.origin.y, rectangle.size.width - (blockPoint.x - rectangle.origin.x), rectangle.size.height); 
     } 
     [rectangleArray replaceObjectAtIndex:[rectangleArray indexOfObject:val] withObject:[NSValue valueWithCGRect:newRectangle]]; 
     [rectangleArray addObject:[NSValue valueWithCGRect:addRectangle]]; 
    } 
} 

这是为什么崩溃的地步?

+0

发生崩溃时,控制台中几乎总是有消息。你应该在你的文章中包含这些内容。 –

您正在尝试在枚举枚举数组时(在代码的开头为“for循环”)尝试对数组进行变形(使用“replaceObjectAtIndex:”)。这引发了一个例外。你应该看到它在控制台日志中,这样的事情:

 
Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection was mutated while being enumerated. 

你能做什么,而不是是先枚举,然后确定要发生变异的对象,将它们存储在另一个集合类(一个NSSet中或其他NSArray)并最终将收集到的项目应用到原始数组中。 或者另一种可能性是您复制第一个数组,然后枚举副本并对原始数组进行更改。

+0

[rectangleArray addObject:[NSValue valueWithCGRect:addRectangle]];会导致碰撞很好。只是事实证明它在碰到该部分之前崩溃了 –

+0

原因相同:在枚举时不能更改可变数组;这是运行时环境引发的异常,以保持集合的完整性。 – viggio24

我之前在我的代码中遇到过这个问题,并且让我猜想,您已经在您的initinitWith....方法中创建了该数组,对吧?

若要在init方法中正确创建带代码的属性(即不是来自Interface Builder的UI控件),请使用总是保留您的财产。

总之,

myNSMutableArray = [[NSMutableArray alloc] initWith....]; 

应该

myNSMutableArray = [[[NSMutableArray alloc] initWith....] retain]; 

这样,即使你的init方法结束的myNSMutableArray保留计数将防止系统来释放/释放你的对象。

或者,因为你在声明(保留)方式的属性,可以使用

self.myNSMutableArray = [[NSMutableArray alloc] initWith...]; 

使用访问将做保留你。