Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Crash - "Collection <CALayerArray: 0x645dfc0> was mutated while being enumerated."

Goal is to "launch a spinner graphic at start of viewWillAppear that loads data before showing the tableview" so the user doesn't wonder why there's a delay before seeing the table. I.e. a UIActivityIndicatorView has been added to the window, and I just want to set the alpha to hide/show it.

I get this strange error when starting a thread to make sure the "spinning gears" imageview (tag=333) gets shown, before moving on to load/calculate stuff in viewWillAppear.

I don't get it on every call to [appdel addGearz] and [appdel removeGearz], it happens for both these, and it's random. It can happen after 2 viewWillAppears, or after 15. If I comment out the line that sets the alpha, everything works.

A typical viewWillAppear looks something like this,

[super viewWillappear];
self.title=@"Products listing"; //and other simple things
[appdel addGearz];
[self getProducts];
[self getThumbnails];
[myTableView reloadData]; //in case view already loaded and coming back from subview and data changed

And here is the code that crashes if the lines with .alpha are not commented out

-(void)addGearz {
    [NSThread detachNewThreadSelector:@selector(gearzOn) toTarget:self withObject:nil];
}

-(void)removeGearz {
    [NSThread detachNewThreadSelector:@selector(gearzOff) toTarget:self withObject:nil];
}

- (void)gearzOn {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [window viewWithTag:333].alpha=1.0;
        //
        //  [[window viewWithTag:333] setNeedsDisplay];
    [pool drain];
}

- (void) gearzOff {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [window viewWithTag:333].alpha=0.0;
        //
        //  [[window viewWithTag:333] setNeedsDisplay];
    [pool drain];
}

I've used someone else's code, so... anything obvious you can see? Surely I must be able to change alpha of UIViews in a thread? Do I need to "embed" the alpha-change in some "stop enumerating while I change this"-code?

I made it not crash by moving that alpha-change-line to above the pool alloc or below the [pool drain], but then I get a lot of "autoreleased with no pool in place - just leaking"-messages.

Apparently, there's something I don't understand about this thread code.

like image 237
Henrik Erlandsson Avatar asked Jan 21 '11 10:01

Henrik Erlandsson


1 Answers

You must not try to modify the UI on a separate thread. UI should only be manipulated on the main thread.

Instead of detaching a new thread, you should use performSelectorOnMainThread:withObject:waitUntilDone:. This will ensure that the method will be called on the proper thread.

like image 84
Laurent Etiemble Avatar answered Nov 04 '22 23:11

Laurent Etiemble