removeFromSuperview上的EXC_BAD_ACCESS错误调用NSMutableArray中的视图

时间:2014-12-12 22:51:51

标签: ios objective-c

当我尝试从它的superview中删除我之前存储在NSMutableArray中的UIView时,我一直收到EXC_BAD_ACCESS错误。这是我正在使用的代码:

int transRemoveIdx = -1;
for(int i = 0; i < [transparentTiles count]; i++){
    UIView *transparentView = [transparentTiles objectAtIndex:i];
    int transparentViewX = transparentView.frame.origin.x;
    int transparentViewY = transparentView.frame.origin.y;
    NSLog(@"Transparent X: %d Transparent Y: %d", transparentViewX, transparentViewY);

    if(transparentViewX == x && transparentViewY == y && !solid){
        [[transparentTiles objectAtIndex:i] removeFromSuperview];
        transRemoveIdx = i;
        break;
    }
}
if(transRemoveIdx != -1){
    [transparentTiles removeObjectAtIndex:transRemoveIdx];
}


if(solid){
    [solidTiles addObject:newView];
}else{
    NSLog(@"Adding Tile: %d", tileId);
    [transparentTiles addObject:newView];
}

[mapScroll addSubview:newView];
[mapScroll sendSubviewToBack:newView];

这是transparentTiles的初始化:

transparentTiles = [[NSMutableArray alloc] init];

这将检查是否已将瓷砖放置在我想要放置的位置,如果有,则会移除旧瓷砖以留出新瓷砖的空间。或者至少这就是我想要它做的事情,但是我得到的EXC_BAD_ACCESS错误大约是调用[[transparentTiles objectAtIndex:i] removeFromSuperview];的一半时间。

我无法弄清楚什么时候会发生,似乎是完全随机的。有没有办法确保不再发生这种情况?非常感谢任何帮助,谢谢!

更新

我发现导致问题的唯一代码是removeFromSuperview代码。如果我要更换线

[[transparentTiles objectAtIndex:i] removeFromSuperview];

[[transparentTiles objectAtIndex:i] setAlpha:0.0f];
然后一切都完美无缺。我不确定为什么removeFromSuperview会导致EXC_BAD_ACCESS调用,但我现在正在将tile的alpha设置为空,所以它消失了,这基本上完成了我正在尝试做的事情。任何人都知道为什么调用removeFromSuperview会导致此错误?

3 个答案:

答案 0 :(得分:1)

从您发布的代码看起来您​​继续添加磁贴,但您永远不会删除它们。 所以相同的视图可以在transparentTiles数组中n次导致n次调用removeFromSuperview?仍然不应该崩溃(不是没有线程),但它是1.可疑的东西

答案 1 :(得分:1)

 [transparentTiles removeObjectAtIndex:i]; 

- &GT;这会导致你的问题。枚举可变集合时我们不会删除对象。

for(int i = 0; i < [transparentTiles count]; i++){
   ...

    if(transparentViewX == x && transparentViewY == y && !solid){
        [[transparentTiles objectAtIndex:i] removeFromSuperview]; //this is the line that causes the error to be called
        [transparentTiles removeObjectAtIndex:i];
    }
}

想象一下,您的transparentTitles有3个项目。 for循环将运行3次。如果'removeObjectAtIndex:i'在第二个循环中执行,则在第三个循环中,调用objectAtIndex:2将崩溃,因为您的transparentTitles现在有2个项而不是3个。

我的解决方案是:将要删除的视图添加到另一个NSMutableArray(例如:_temp),然后在您的过程结束时,从您的transparentTitles中删除_temp中存在的所有项目

答案 2 :(得分:0)

像这样删除。所以崩溃永远不会发生: -

1)如果你想删除以下所有尝试: -

[yourVw.subViews performSelector:@selector(removeFromSuperView:)]

2)如果你想删除任何特定的例如

for (id vw in yourVw.subViews)
{
if ([vw isKindOfClass:[NSTextField class])
{
[vw removeFromSuperView]
}
}