我的 iPhone 应用程序偶尔会崩溃,并出现以下异常
NSGenericException', reason: '*** Collection <CALayerArray: 0x26f6b0> was mutated while being enumerated.
崩溃线程上的堆栈跟踪
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
执行以下代码后会触发此崩溃。
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];
这对任何人来说都是明显错误的吗?我目前的想法是,这要么与在推送之前释放 stopVC 相关,要么与 navigationController.view 进行转换,同时将新的 viewController 推送到 navigationController。
由于这种情况只是偶尔发生,因此我希望在进行潜在修复之前更有信心。
最佳答案
是的,这是 API 的错误用法。 -[UINavigationController PushViewController:animated:] 自行处理动画。即使您传递 NO 作为第二个参数,它仍然在操纵 View 层次结构,这就是导致崩溃的原因。
基本上,没有理由像您所做的那样在动画 block 中调用 -[UINavigationController PushViewController:animated:] 。如果您想为 Controller 的插入设置动画,请传递 YES 作为第二个参数。
关于iphone - UIView 转换期间的枚举突变WithView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4341163/