I am creating an app that starts with a CGRect that is the size of the screen. when the users touches inside of the CGRect it is cut into two CGRects. I get this to work just fine when I touch inside of the new CGRect that is created, but when I touch within a CGRect that is not the latest one added to the rectangleArray the app crashes and says sigabrt.
Here is the code in touchesBegan, blockPoint is the point where the screen is touched
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]];
}
}
Why is this crashing?
You’re trying to mutate the array (with “replaceObjectAtIndex:”) while enumerating it (the “for loop” at the beginning of your code). This rises an exception. You should see it in the console log, something like this:
What you can do instead is to first enumerate, then identify the objects you want to mutate, store them in another collection class (a NSSet or another NSArray) and finally apply the collected items in the original array.
Or another possibility is you make a copy of the first array, then enumerate the copy and do the changes to the original array.