ios 集合〈CALayerArray:0x1ed8faa0>在枚举时发生突变

w1jd8yoj  于 2022-11-26  发布在  iOS
关注(0)|答案(4)|浏览(143)

我的应用程序崩溃了一段时间,而从屏幕上删除等待视图。请指导我如何改进下面给出的代码。
等待视图只在应用程序从服务器下载东西时调用。当它完成下载时,我调用removeWaitView方法。

例外类型:NS一般例外状况
**原因:**枚举时集合发生变化。

+(void) removeWaitView:(UIView *) view{
    NSLog(@"Shared->removeWaitView:");
    UIView *temp=nil;
    temp=[view viewWithTag:kWaitViewTag];
    if (temp!=nil) {
        [temp removeFromSuperview];
    }
}

我的waitview添加代码是

+(void) showWaitViewInView:(UIView *)view withText:(NSString *)text{
   NSLog(@"Shared->showWaitViewWithtag");
   UIView *temp=nil;
   temp=[view viewWithTag:kWaitViewTag];
   if (temp!=nil)
   {
       return;
   }
   //width 110 height 40
   WaitViewByIqbal *waitView=[[WaitViewByIqbal alloc] initWithFrame:CGRectMake(0,0,90,35)];
   waitView.center=CGPointMake(view.frame.size.width/2,(view.frame.size. height/2) -15); 
   waitView.tag=kWaitViewTag;    // waitView.waitLabel.text=text;
   [view addSubview:waitView];
   [waitView release]; 
}
5anewei6

5anewei61#

例外情况非常明显--一个集合(在本例中类似于数组)在被修改的同时也在被枚举。
在这个特定的例子中,我们讨论的是层的数组,或者更确切地说,是UIView的示例,它们都是由层备份的。
当您呼叫removeFromSuperviewaddSubview时,会发生修改。枚举会在重新绘制期间的任何时间发生。
我的猜测是-您没有从主线程调用您的方法,并且主线程当前正在重绘,因此您将得到一个竞态条件。
解决方案:仅从主线程调用这些方法。

g6baxovj

g6baxovj2#

你应该得到一个数组的副本,这样你就不会冒着在你的代码枚举它的时候它被修改的风险。当然,这也留下了一个可能的机会,一个新的项目可能会作为变异的结果被添加,这样你的枚举就会错过一个数组项目。下面是一个针对你的问题标题的例子:

[[viewLayer.sublayers copy] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            CALayer * subLayer = obj;
            if(subLayer == theLayerToBeDeleted){
                [subLayer removeFromSuperlayer];
            }

        }];
h4cxqtbf

h4cxqtbf3#

有可能您在添加或删除waitView的同时,还在遍历waitView的同级视图(它是superView的子视图)。请检查哪些方法调用了removeWaitViewshowWaitInView,以确保调用方法不会在遍历waitView的同级视图(waitView的superView的子视图)的for循环中调用show/remove wait view方法。

ddarikpa

ddarikpa4#

要修复问题,只需从最后一个元素开始

NSMutableArray* Items = [[NSMutableArray alloc] initWithArray:[_ScrollList.documentView subviews]];
while ([Items count]>0) {
    NSView *v = [Items lastObject];
    [v removeFromSuperview];
    [Items removeLastObject];
}

相关问题