Enumeration Mutation During UIView transitionWithView

0

I'm experience an occasional crash of my iPhone application where I'm getting the following exception

NSGenericException', reason: '*** Collection <CALayerArray: 0x26f6b0> was mutated while being enumerated.

With the stack trace on the crashing thread of

Thread 0 Crashed:
0   libSystem.B.dylib                   0x00078ac8 __kill + 8
1   libSystem.B.dylib                   0x00078ab8 kill + 4
2   libSystem.B.dylib                   0x00078aaa raise + 10
3   libSystem.B.dylib                   0x0008d03a abort + 50
4   libstdc++.6.dylib                   0x00044a20 __gnu_cxx::__verbose_terminate_handler() + 376
5   libobjc.A.dylib                     0x00005958 _objc_terminate + 104
6   libstdc++.6.dylib                   0x00042df2 __cxxabiv1::__terminate(void (*)()) + 46
7   libstdc++.6.dylib                   0x00042e46 std::terminate() + 10
8   libstdc++.6.dylib                   0x00042f16 __cxa_throw + 78
9   libobjc.A.dylib                     0x00004838 objc_exception_throw + 64
10  CoreFoundation                      0x0009f850 __NSFastEnumerationMutationHandler + 208
11  libobjc.A.dylib                     0x0000a51a objc_enumerationMutation + 18
12  UIKit                               0x00007bfe -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 142
13  UIKit                               0x00007c2e -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 190
14  UIKit                               0x00007cd2 -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:] + 22
15  UIKit                               0x00007628 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 304
16  UIKit                               0x000074e8 -[UIView(Hierarchy) addSubview:] + 16
17  UIKit                               0x0006c350 +[UIViewControllerWrapperView wrapperViewForView:frame:] + 232
18  UIKit                               0x00077d0c -[UINavigationController _startTransition:fromViewController:toViewController:] + 468
19  UIKit                               0x00077abc -[UINavigationController _startDeferredTransitionIfNeeded] + 176
20  UIKit                               0x00077a00 -[UINavigationController viewWillLayoutSubviews] + 8
21  UIKit                               0x0006dca8 -[UILayoutContainerView layoutSubviews] + 132
22  UIKit                               0x0000fbc0 -[UIView(CALayerDelegate) _layoutSublayersOfLayer:] + 20
23  CoreFoundation                      0x0003e2e4 -[NSObject(NSObject) performSelector:withObject:] + 16
24  QuartzCore                          0x0000f942 -[CALayer layoutSublayers] + 114
25  QuartzCore                          0x0000f6fa CALayerLayoutIfNeeded + 178
26  QuartzCore                          0x000094c4 CA::Context::commit_transaction(CA::Transaction*) + 204
27  QuartzCore                          0x000092da CA::Transaction::commit() + 186
28  QuartzCore                          0x0002d9b6 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 46
29  CoreFoundation                      0x00030236 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 10
30  CoreFoundation                      0x000300aa __CFRunLoopDoObservers + 406
31  CoreFoundation                      0x000276b4 __CFRunLoopRun + 848
32  CoreFoundation                      0x00027270 CFRunLoopRunSpecific + 224
33  CoreFoundation                      0x00027178 CFRunLoopRunInMode + 52
34  GraphicsServices                    0x000045ec GSEventRunModal + 108
35  GraphicsServices                    0x00004698 GSEventRun + 56
36  UIKit                               0x0000411c -[UIApplication _run] + 396
37  UIKit                               0x00002128 UIApplicationMain + 664
38  iDriveGreen                         0x00003026 main (main.m:13)
39  iDriveGreen                         0x00002ff0 start + 32

This crash is being triggered after the following code is executed.

StopRouteViewController *stopVC = [[StopRouteViewController alloc] init];   
[UIView transitionWithView:self.navigationController.view
                  duration:0.5
                   options:UIViewAnimationOptionTransitionFlipFromLeft
                animations:^{
                    [self.navigationController pushViewController:stopVC animated:NO];
                }
                completion:NULL];
[stopVC release];

Does this look blatantly wrong to anyone? My current thought is that is is either tied to stopVC being released before it is pushed or with transitioning with navigationController.view while at the same time pushing a new viewController to the navigationController.

Since this only occurs occasionally, I'd like to have a little more confidence before I commit a potential fix.

iphone
objective-c
cocoa-touch
ios
uikit
asked on Stack Overflow Dec 2, 2010 by matheeeny

1 Answer

1

Yes, this is incorrect usage of the API. -[UINavigationController pushViewController:animated:] handles animation on its own. Even if you pass NO as the second argument, it is still manipulating the view hierarchy, which is what's causing your crash.

Basically, there is no reason to put a call to -[UINavigationController pushViewController:animated:] in an animation block, as you have done. If you want to animate the push of your controller, pass YES as the second argument.

answered on Stack Overflow Dec 3, 2010 by Ryan

User contributions licensed under CC BY-SA 3.0