iOS dismissModalViewController导致EXC_BAD_ACCESS

时间:2012-03-28 15:40:36

标签: ios xcode exc-bad-access modalviewcontroller

调用dismissModalViewController会间歇性地导致EXC_BAD_ACCESs。

间歇性与特定构建有关,而不是特定的构建。也就是说,如果已编译可执行文件,则调用将始终通过或始终失败。

它似乎并不依赖于代码是否在构建之间发生了变化。

我们正在使用安装了iOS 5.1的iPhone 5.1模拟器和iPod touch第4代。模拟和物理设备中都存在此行为

有没有人见过这个?我们已经结束了。

以下是模态视图控制器的显示位置以及被解除的位置:

PaymentStack* paymentStack = 
[[PaymentStack alloc] initWithOrder:[anOrderManager thisOrder] locationState:[appData locationState]
                       successBlock:^{
                           //Push the current order on the history list
                           [[appData ordersHistory] addObject:[anOrderManager thisOrder]];
                           if ([[anOrderManager thisOrder] isEffectivelyEqual:[anOrderManager thisOrder]])
                           {
                               //Allocate a new order
                               [anOrderManager setOrder:[[Order alloc] init]];
                           }
                       }
                    completionBlock:^{

                        [self dismissViewControllerAnimated:YES 
                                                 completion:^{
                                                     NSLog(@"Complete.");
                                                 }];
                    }
                  cancellationBlock:^{
                      [self dismissViewControllerAnimated:YES 
                                               completion:^{
                                                   NSLog(@"Cancellation.");
                                               }];
                  }];
[self presentModalViewController:[paymentStack navigationController] animated:YES];

这是堆栈跟踪:

#0  0x00d659ab in -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] ()
#1  0x00b4ea9c in -[UIViewController _dismissViewControllerWithTransition:from:completion:] ()
#2  0x00b4df91 in -[UIViewController dismissViewControllerWithTransition:completion:] ()
#3  0x00b4ec81 in -[UIViewController dismissViewControllerAnimated:completion:] ()
#4  0x00071135 in __35-[MasterViewController placeOrder:]_block_invoke_0186 at /Users/jake/Documents/Avocado/AvocadoTest1.0/MasterViewController.m:258
#5  0x000515c0 in __91-[PaymentStack initWithOrder:locationState:successBlock:completionBlock:cancellationBlock:]_block_invoke_0 ()
#6  0x000545c8 in __27-[PaymentStack showSuccess]_block_invoke_0230 ()
#7  0x000558cc in -[PaymentCompleteViewController done] ()
#8  0x01a47e99 in -[NSObject performSelector:withObject:withObject:] ()
#9  0x00a8214e in -[UIApplication sendAction:to:from:forEvent:] ()
#10 0x00cc0a0e in -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] ()
#11 0x01a47e99 in -[NSObject performSelector:withObject:withObject:] ()
#12 0x00a8214e in -[UIApplication sendAction:to:from:forEvent:] ()
#13 0x00a820e6 in -[UIApplication sendAction:toTarget:fromSender:forEvent:] ()
#14 0x00b28ade in -[UIControl sendAction:to:forEvent:] ()
#15 0x00b28fa7 in -[UIControl(Internal) _sendActionsForEvents:withEvent:] ()
#16 0x00b28266 in -[UIControl touchesEnded:withEvent:] ()
#17 0x00aa73c0 in -[UIWindow _sendTouchesForEvent:] ()
#18 0x00aa75e6 in -[UIWindow sendEvent:] ()
#19 0x00a8ddc4 in -[UIApplication sendEvent:] ()
#20 0x00a81634 in _UIApplicationHandleEvent ()
#21 0x03dd9ef5 in PurpleEventCallback ()
#22 0x01a1a195 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ ()
#23 0x0197eff2 in __CFRunLoopDoSource1 ()
#24 0x0197d8da in __CFRunLoopRun ()
#25 0x0197cd84 in CFRunLoopRunSpecific ()
#26 0x0197cc9b in CFRunLoopRunInMode ()
#27 0x03dd87d8 in GSEventRunModal ()
#28 0x03dd888a in GSEventRun ()
#29 0x00a7f626 in UIApplicationMain ()
#30 0x000025ed in main at /Users/jake/Documents/Avocado/AvocadoTest1.0/AvocadoTest1/main.m:16

如果有更好的方式可以为您格式化,请告诉我。

3 个答案:

答案 0 :(得分:1)

当你运行类似的东西时:

[self dismissViewControllerAnimated:YES 
                         completion:^{
                                     NSLog(@"Complete.");
                                     }];

在一个区块内运行类似:

[self presentModalViewController:[paymentStack navigationController] animated:YES];

在块之外,不可能知道哪行代码首先运行。有时它会是dismissViewControllerAnimated:,有时它将是presentModalViewController:。

如果dismissViewControllerAnimated:先运行,那么viewController可能会被释放,因此当应用程序尝试运行presentModalViewController时:它正在向不再存在的对象发送消息,这可能是导致崩溃的原因。

祝你好运!

答案 1 :(得分:1)

我遇到的问题(与此症状相同)原来是(经过一整天的调试!)以下情况:

1)视图控制器A呈现(使用presentViewController:animated:completion :)视图控制器B.

2)视图控制器B保持对视图控制器A(委托参考)的弱引用。

3)视图控制器B在视图控制器A上执行一个方法,作为副作用,它释放视图控制器A.

4)视图控制器B尝试使用以下方法解除自身:

[self dismissViewControllerAnimated:NO completion:completion];

跟踪此问题的部分困难来自步骤3)异步。步骤4)正在发生,步骤3)尚未完成。即,视图控制器B在步骤4)中被解除分配。

答案 2 :(得分:0)

尝试保存2个强指针:一个用于PaymentStack viewController,另一个用于“self”。它将有助于发现谁被摧毁。 为每个viewControllers添加“ - (void)dealloc”方法,并为这些方法添加断点。它将有助于发现破坏点。