Reputation: 4617
My app crashes some time while removing wait view from screen. Please guide me how can i improve code given below.
The wait view is only called when app is downloading something from server. and when it completed download then i call removeWaitView method.
Exception Type: NSGenericException
Reason: Collection was mutated while being enumerated.
+(void) removeWaitView:(UIView *) view{
NSLog(@"Shared->removeWaitView:");
UIView *temp=nil;
temp=[view viewWithTag:kWaitViewTag];
if (temp!=nil) {
[temp removeFromSuperview];
}
}
my waitview adding code is
+(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];
}
Upvotes: 10
Views: 8771
Reputation: 1
To fix issue just start from last element
NSMutableArray* Items = [[NSMutableArray alloc] initWithArray:[_ScrollList.documentView subviews]];
while ([Items count]>0) {
NSView *v = [Items lastObject];
[v removeFromSuperview];
[Items removeLastObject];
}
Upvotes: 0
Reputation: 149
You should get a copy of the array, so you don't risk the chance of it being modified while your code is enumerating it. Of course this leaves the chance that a new item may be added as a result of the mutation, thus your enumeration will miss that one array item. Here is an example specific to the title of your question:
[[viewLayer.sublayers copy] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
CALayer * subLayer = obj;
if(subLayer == theLayerToBeDeleted){
[subLayer removeFromSuperlayer];
}
}];
Upvotes: 6
Reputation: 8502
It's possible that you're adding or removing a the waitView while iterating through the waitView's siblings (it's superView's subviews). Check to see what methods call removeWaitView
and showWaitInView
to make sure the calling methods don't call the show/remove wait view methods from within a for loop iterating the wait view's siblings (the waitView's superview's subviews).
Upvotes: 3
Reputation: 130092
The exception is pretty clear - a collection (in this case something like an array) is being modified while it is also being enumerated.
In this specific case we are talking about array of layers, or better said, instances of UIView
which are all backed up by layers.
The modifications happen when you are calling removeFromSuperview
or addSubview
. The enumeration can happen anytime during redrawing.
My guess is - you are not calling your methods from the main thread and the main thread is currently redrawing, so you'll get a racing condition.
Solution: call these methods only from the main thread.
Upvotes: 18