当我尝试从它的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会导致此错误?
答案 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]
}
}