将对象添加到导致崩溃的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]];
}
}
这是为什么崩溃的地步?
您正在尝试在枚举枚举数组时(在代码的开头为“for循环”)尝试对数组进行变形(使用“replaceObjectAtIndex:”)。这引发了一个例外。你应该看到它在控制台日志中,这样的事情:
Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection was mutated while being enumerated.
你能做什么,而不是是先枚举,然后确定要发生变异的对象,将它们存储在另一个集合类(一个NSSet中或其他NSArray)并最终将收集到的项目应用到原始数组中。 或者另一种可能性是您复制第一个数组,然后枚举副本并对原始数组进行更改。
[rectangleArray addObject:[NSValue valueWithCGRect:addRectangle]];会导致碰撞很好。只是事实证明它在碰到该部分之前崩溃了 –
原因相同:在枚举时不能更改可变数组;这是运行时环境引发的异常,以保持集合的完整性。 – viggio24
我之前在我的代码中遇到过这个问题,并且让我猜想,您已经在您的init
或initWith....
方法中创建了该数组,对吧?
若要在init
方法中正确创建带代码的属性(即不是来自Interface Builder的UI控件),请使用总是保留您的财产。
总之,
myNSMutableArray = [[NSMutableArray alloc] initWith....];
应该
myNSMutableArray = [[[NSMutableArray alloc] initWith....] retain];
这样,即使你的init
方法结束的myNSMutableArray
保留计数将防止系统来释放/释放你的对象。
或者,因为你在声明(保留)方式的属性,可以使用
self.myNSMutableArray = [[NSMutableArray alloc] initWith...];
使用访问将做保留你。
发生崩溃时,控制台中几乎总是有消息。你应该在你的文章中包含这些内容。 –