UIScrollView EXC_BAD_ACCESS在iOS SDK中崩溃

我有一个iPhone SDK应用程序,有几个视图出现和消失用户创build内容。 在设备上使用应用程序一段时间后,我得到以下的崩溃:

Program received signal: “EXC_BAD_ACCESS”. (gdb) backtrace #0 0x33369ebc in objc_msgSend () #1 0x320e5248 in -[UIScrollView(UIScrollViewInternal) _scrollViewAnimationEnded] () #2 0x338b4a14 in -[NSObject performSelector:withObject:] () #3 0x320e5098 in -[UIAnimator stopAnimation:] () #4 0x320e4b7c in -[UIAnimator(Static) _advance:] () #5 0x320e4a34 in LCDHeartbeatCallback () #6 0x34350e60 in HeartbeatVBLCallback () #7 0x332e91c0 in IOMobileFramebufferNotifyFunc () #8 0x316532f8 in ?? () #9 0x33866b50 in __CFMachPortPerform () #10 0x338ae52a in CFRunLoopRunSpecific () #11 0x338adc1e in CFRunLoopRunInMode () #12 0x3434e1c8 in GSEventRunModal () #13 0x32002c30 in -[UIApplication _run] () #14 0x32001230 in UIApplicationMain () #15 0x00002ff8 in main (argc=1, argv=0x2ffff550) at /Developer/svn/MyCompany/iPhone/MyApplication/Other Sources/main.m:14 

正如你从跟踪中可以看到的那样,那里唯一提到我的代码是调用main。

我已经从Xcode运行生成和分析,也设置它从我的项目从terminal上运行铛分析器,这两个都不能find代码中的任何问题。 我正在使用最新版本的iOS SDK(我还没有下载4.1,但是我正在使用的是4.1版本之前的版本)。

此外,我已经在模拟器中运行仪器中的应用程序,该应用程序没有内存泄漏。

我即将尝试使用NSZombieEnabledvariables,看看是否有什么发现,但问题是,我需要使用该应用程序30至40分钟左右之前,崩溃,我怀疑, NSZombieEnabled甚至可能不帮我找问题。

看起来像我遇到的崩溃是当一个模式视图调用父视图控制器中的委托。 父视图控制器然后在解除模态视图控制器之前进行一些处理。 在崩溃中有一些引用来animation和滚动视图,但我不知道我能做些什么来导致这些问题。 有没有人有任何build议寻找的东西?

编辑:我已经将NSZombieEnabled标志放入应用程序,并在设备上,它在控制台中出现此消息:

 2010-09-11 17:10:33.970 MyApplication[9321:207] *** -[MyViewController respondsToSelector:]: message sent to deallocated instance 0x7489480 

据我所知,我将应用程序中使用的代表设置为全部类的dealloc中的零,所以我被困在了接下来的位置。

我试图使用malloc_history pid地址命令,但它说,它找不到过程,我试过9321,9321:207和207.另外,如果我尝试使用MallocStackLoggingvariables,程序将不运行在设备上,我得到了一堆malloc:无法在控制台中创build堆栈日志目录消息和程序崩溃。

哦,顺便说一句,我不能在Instrument中使用僵尸检查,因为它似乎不能用于设备,而且我也无法在模拟器中发生同样的崩溃。

堆栈帧#1上的UIScrollView可能想要通知其代表关于animation结束,但委托在这一点上消失。 设置NSZombieEnabled可能会证实这一点。

代表不被保留,所以这是Cocoa和Cocoa Touch中的一个常见错误。 在代码中查找UIScrollViewUITableView上的委托,并尝试查找哪个可能在其时间之前被释放。

我只是自己解决了这个问题。

我遇到了一个问题:

  • scrollview委托连线到UIViewController
  • scrollview开始animation
  • 代表走了,dealloc被叫了。

问题是scrollview委托消息在新的解除分配的对象上触发,并且崩溃日志有点混乱,因为它们指向无意义的对象引用。

解决的办法是将scrollview委托设置为nil作为我的视图控制器dealloc方法的第一行。

希望这可以帮助别人!

为了完整性,我添加了这个堆栈跟踪(iOS 6),可能会遇到同样的问题,但有一点不同的实现和确切的步骤来重现问题的人。

 Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Codes: KERN_INVALID_ADDRESS at 0x71f05631 Crashed Thread: 0 Thread 0 name: Dispatch queue: com.apple.main-thread Thread 0 Crashed: 0 libobjc.A.dylib 0x3919b5d0 objc_msgSend + 1 1 UIKit 0x33421830 -[UIScrollView(UIScrollViewInternal) _delegateScrollViewAnimationEnded] + 48 2 UIKit 0x334217ba -[UIScrollView(UIScrollViewInternal) _scrollViewAnimationEnded:finished:] + 130 3 UIKit 0x334216a4 -[UIAnimator stopAnimation:] + 460 

这发生在iOS 6上,并且在我实现UIScrollViewDelegate方法时开始发生:

 " -(void)scrollViewDidEndDecelerating:(UITableView *)tableView" and made a call to: "[tableView scrollToRowAtIndexPath: indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];". 

animation开始时,出现了问题,我按下了“返回”button,我的视图控制器在animation完成之前popup。

在复制时,一定要在animation开始之后但完成之前按下“返回”button。 我花了几次尝试。 我试图通过编程popup视图控制器重新创build问题,但无法重现它。 我不得不使用“返回”button。 我只是在dealloc中调用[myTableView版本]。 解决scheme如下所述将这两个属性设置为零:

 self.myTableView.delegate = nil; self.myTableView = nil; 

首先, 代表应该是弱/分配types的。 但事件在这种情况下,有一个非常常见的细微的障碍,由滚动animation驱动。 如果您为ScrollView使用animation内容偏移更改,则强烈需要使用dealloc方法将其委托设置为nil

否则,你会得到以下

 [YourViewController respondsToSelector:]: message sent to deallocated instance 

最常见的例子是:

 1. _tableView is ivar of YourViewController 2. _tableView.delegate = self; 3. - (void)scrollViewDidScroll:(UIScrollView *)scrollView is implemented at YourViewController 4. at some point you call [_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; or [_tableView setContentOffset:CGPoint animated:YES] and try to close YourViewController 

_tableView由CoreAnimation保留,但YourViewController被释放!

我的猜测是将scrollview的委托设置为已被释放的对象。 尝试设置子对象的所有代表在你的dealloc方法中为零。

这可能会发生,如果你插入一个刷新控制器到一个子视图(我的提示,从来没有这样做)…

以上所有都没有解决我的问题,所以我深深地挖了我的代码。 我认识到,当我执行键盘和UICollectionViewanimation(是的,这是一个聊天),并解雇当前的控制器出现崩溃。

应用程序崩溃,因为我尝试在animation完成块中滚动:)

把它切好,现在一切正常!

快乐的编码和debugging:)

面对同样的问题,我设置了:

 self.collectionView.delegate = nil; 

- (void)viewDidLoad (在实际设置ViewController为collectionView委托之前)和-(void)viewWillDisappear:(BOOL)animated

现在一切正常。

感谢帮助。

我见过这样的行为,当调用scrollToRowAtIndexPath不存在索引path