Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/100.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 收藏<;CALayerArray:0x1ed8faa0>;在枚举时发生了变异_Iphone_Ios_Objective C - Fatal编程技术网

Iphone 收藏<;CALayerArray:0x1ed8faa0>;在枚举时发生了变异

Iphone 收藏<;CALayerArray:0x1ed8faa0>;在枚举时发生了变异,iphone,ios,objective-c,Iphone,Ios,Objective C,从屏幕上删除等待视图时,我的应用程序崩溃了一段时间。请指导我如何改进下面给出的代码 仅当应用程序正在从服务器下载某些内容时,才会调用“等待”视图。当它完成下载后,我调用removeWaitView方法 异常类型:NSGenericeException 原因:集合在枚举时发生了变异 +(void) removeWaitView:(UIView *) view{ NSLog(@"Shared->removeWaitView:"); UIView *temp=nil;

从屏幕上删除等待视图时,我的应用程序崩溃了一段时间。请指导我如何改进下面给出的代码


仅当应用程序正在从服务器下载某些内容时,才会调用“等待”视图。当它完成下载后,我调用removeWaitView方法

异常类型:NSGenericeException

原因:集合在枚举时发生了变异

+(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]; 
}

例外情况很明显——一个集合(在本例中类似于数组)在被修改的同时也在被枚举

+(void) removeWaitView:(UIView *) view{
    NSLog(@"Shared->removeWaitView:");
    UIView *temp=nil;
    temp=[view viewWithTag:kWaitViewTag];
    if (temp!=nil) {
        [temp removeFromSuperview];
    }
}
在本例中,我们讨论的是层的数组,或者更好地说,是由层备份的
UIView
的实例

在调用
removeFromSuperview
addSubview
时会发生修改。枚举可以在重绘期间随时发生

我的猜测是-您没有从主线程调用您的方法,并且主线程当前正在重新绘制,因此您将获得一个竞速条件


解决方案:仅从主线程调用这些方法。

在遍历waitView的同级(它是superView的子视图)时,您可能在waitView中添加或删除一个对象。检查哪些方法调用了
removeWaitView
showWaitInView
,以确保调用方法不会在for循环中调用show/remove wait view方法,该循环迭代wait view的兄弟(waitView的superview的子视图)。

您应该获得数组的副本,因此,在代码枚举时,您不会冒被修改的风险。当然,这留下了一个机会,一个新的项目可能会被添加作为突变的结果,因此您的枚举将错过一个数组项目。以下是问题标题的具体示例:

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

        }];

查看异常的完整回溯将非常有用。(如果您不确定如何查找此信息,您可能可以在Google上搜索。)如何调用
removeWaitView
?嗯。我总是尝试在主线程上调用类似的方法,但在我看来您是对的,因为此异常只能在未从主线程调用时出现(根据我的代码)。开发者亚伦·海曼的回答是另一种可能的解释。从堆栈跟踪中可以明显看出。非常聪明的分析。谢谢。是的,如果我在循环中使用过,这可能会产生问题。不,我不是在循环中使用它。由于我已经编辑了我的问题,非常感谢您的帮助。通常,循环内的显性突变是最常见的罪魁祸首。但是突变也可能发生在另一个线程中(sulthan指出)。