-1

我正在创建一个以屏幕大小的 CGRect 开头的应用程序。当用户触摸 CGRect 内部时,它会被切割成两个 CGRect。当我触摸创建的新 CGRect 内部时,我让它工作得很好,但是当我触摸一个不是最新添加到 rectangleArray 的 CGRect 中时,应用程序崩溃并显示 sigabrt。

这里是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]];
    }
}

为什么会崩溃?

4

2 回答 2

1

您正在尝试在枚举数组(代码开头的“for循环”)时改变数组(使用“replaceObjectAtIndex:”)。这引发了一个例外。您应该在控制台日志中看到它,如下所示:

由于未捕获的异常“NSGenericException”而终止应用程序,原因:“*** Collection 在枚举时发生了突变。

相反,您可以做的是首先枚举,然后识别要变异的对象,将它们存储在另一个集合类(NSSet 或另一个 NSArray)中,最后将收集的项目应用到原始数组中。或者另一种可能性是您制作第一个数组的副本,然后枚举副本并对原始数组进行更改。

于 2011-11-05T22:12:18.917 回答
0

我之前在我的代码中遇到过这个问题,让我猜猜,你已经在你的initorinitWith....方法中创建了数组,对吧?

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

简而言之,

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

应该

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

这样,即使您的init方法结束,保留计数myNSMutableArray也会阻止系统释放/释放您的对象。

或者,由于您以(保留)方式声明属性,您可以使用

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

使用访问器将为您保留。

于 2011-11-05T22:23:21.277 回答