iOS SDK中的UIScrollView EXC_BAD_ACCESS崩溃

BP.*_*BP. 36 iphone exc-bad-access uiscrollview

我有一个iPhone SDK应用程序,有多个视图在用户创建内容时出现和消失.在设备上使用该应用程序一段时间后,我遇到以下崩溃:

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
Run Code Online (Sandbox Code Playgroud)

从跟踪中可以看出,我在那里唯一提到的代码是对main的调用.

我已经从Xcode运行Build and Analyze,并将其设置为从终端运行我项目中的clang分析器,这两个都无法在代码中找到任何问题.我正在使用最近发布的iOS SDK版本(我还没有下载4.1,但我正在使用的是4.1之前发布的版本).

此外,我已经使用模拟器在Instruments中运行应用程序,并且应用程序没有内存泄漏.

I am about to try to use the NSZombieEnabled variable and see if that finds anything, but the problem is that I need to use the application for 30 to 40 minutes or so before it crashes, and I suspect that NSZombieEnabled may not even help me find the issue.

It seems like the crashes that I have seen is when a modal view calls a delegate in the parent view controller. The parent view controller then does some processing before dismissing the modal view controller. There is some references in the crash to animating and scroll views, but I am not sure what I could be doing to cause those to have problems. Does anyone have any suggestions for things to look for?

EDIT: I have put the NSZombieEnabled flag into the application, and on the device, it comes up with this message in the console:

2010-09-11 17:10:33.970 MyApplication[9321:207] *** 
-[MyViewController respondsToSelector:]: message 
sent to deallocated instance 0x7489480
Run Code Online (Sandbox Code Playgroud)

As far as I can tell, I am setting the delegates used in the application to nil in the deallocs of all my classes, so I am stuck as to where to look next.

I tried to use the malloc_history pid address command on this, but it said that it could not find the process, I tried 9321, 9321:207, and 207. Also, if I try to use the MallocStackLogging variable, the program will not run on the device, I get a bunch of malloc: unable to create stack log directory messages in the console and a program crash.

Oh, and by the way, I can't use the zombies checking in Instruments, since it does not appear to work with a device, and I can't get the same crash to happen in the Simulator.

小智 61

我自己就是解决了这个问题.

我有一个问题:

  • scrollview委托连接到UIViewController
  • scrollview开始制作动画
  • 代表离开了,dealloc被召唤了.

问题是scrollview委托消息在新释放的对象上触发,并且崩溃日志有点令人困惑,因为它们指向无意义的对象引用.

修复是将scrollview委托设置为nil作为我的视图控制器dealloc方法的第一行.

希望这有助于其他人!

  • 你可能不知道你用这个答案救了我多少麻烦,谢谢你:D (5认同)

Nik*_*uhe 42

UIScrollView堆栈帧#1可能想要通知其委托有关动画的结局,但委托在这一点上已经一去不复返了.设置NSZombieEnabled可能会证实这一点.

代理人没有被保留,所以这是Cocoa和Cocoa Touch中的常见错误.寻找对代表UIScrollViewUITableView在你的代码,并试图找出哪一个可能的时间前公布.


小智 16

为了完整性,我正在为那些可能遇到相同问题但有一些不同的实现和重现问题的确切步骤的人添加此堆栈跟踪(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
Run Code Online (Sandbox Code Playgroud)

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

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

动画开始时出现问题,我按下"后退"按钮,在动画完成之前弹出视图控制器.

复制时,必须确保在动画开始后但在完成之前按"返回"按钮.我花了几次尝试.我尝试通过以编程方式弹出视图控制器来重新创建问题,但无法重现它.我不得不使用"后退"按钮.我只是在dealloc中调用[myTableView release].解决方案如此处所述,将这两个属性设置为nil:

self.myTableView.delegate = nil;
self.myTableView = nil;
Run Code Online (Sandbox Code Playgroud)


mal*_*lex 7

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

否则你会得到以下内容

[YourViewController respondsToSelector:]: message sent to deallocated instance
Run Code Online (Sandbox Code Playgroud)

非常常见的例子:

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
Run Code Online (Sandbox Code Playgroud)

CoreAnimation保留_tableView,但是取消分配了YourViewController!

  • CoreAnimation保留了`_tableView`的+1 (3认同)