UICollectionView在unhighlightAllItems上崩溃

我已经得到了iOS 7中与UICollectionView相关的几个崩溃报告。我无法一直重新创build这个崩溃。

Exception Type: SIGSEGV Exception Codes: SEGV_ACCERR at 0x91c4392b Crashed Thread: 0 Application Specific Information: *** Terminating app due to uncaught exception '', reason: '' Thread 0 Crashed: 0 libobjc.A.dylib 0x39dd2b26 objc_msgSend + 6 1 UIKit 0x31fd5eef -[UICollectionView cellForItemAtIndexPath:] + 111 2 UIKit 0x32060bfd -[UICollectionView _unhighlightItemAtIndexPath:animated:notifyDelegate:] + 149 3 UIKit 0x32383947 -[UICollectionView _unhighlightAllItems] + 151 4 UIKit 0x3205f9fb -[UICollectionView touchesBegan:withEvent:] + 367 5 UIKit 0x31fcb101 forwardTouchMethod + 233 6 UIKit 0x31fcb101 forwardTouchMethod + 233 7 UIKit 0x31e3be4b _UIGestureRecognizerUpdate + 5523 8 UIKit 0x31e73c41 -[UIWindow _sendGesturesForEvent:] + 773 9 UIKit 0x31e735e7 -[UIWindow sendEvent:] + 667 10 UIKit 0x31e48a25 -[UIApplication sendEvent:] + 197 11 UIKit 0x31e47221 _UIApplicationHandleEventQueue + 7097 12 CoreFoundation 0x2f69e18b __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15 13 CoreFoundation 0x2f69d6e1 __CFRunLoopDoSources0 + 341 14 CoreFoundation 0x2f69be4f __CFRunLoopRun + 623 15 CoreFoundation 0x2f606ce7 CFRunLoopRunSpecific + 523 16 CoreFoundation 0x2f606acb CFRunLoopRunInMode + 107 17 GraphicsServices 0x342f4283 GSEventRunModal + 139 18 UIKit 0x31ea8a41 UIApplicationMain + 1137 19 JackThreadsIpad 0x000922b7 main (main.m:16) 

应用程序中的UICollectionViewCells共享一个pipe理突出显示的公共超类。 当单元格被突出显示时,alpha会改变。

 - (void)setHighlighted:(BOOL)highlighted { [super setHighlighted:highlighted]; if (highlighted) { self.alpha = 0.8; } else { self.alpha = 1.0; } } 

可以调用[super setHighlighted:高亮显示]导致这样的崩溃? 该应用程序是编译和提交与Xcode 4,只发生在iOS 7上。任何其他的build议,找出发生这种情况。 谢谢你的帮助。

编辑:我能够在debugging器中捕捉到这一点,但仍然不能一致地重现。 崩溃是:

 [NSIndexPath section] message sent to deallocated instance XXXXXXXX 

如果在用户拖动视图时调用reloadData,则可能是原因。

我有类似的崩溃报告与此相关的崩溃和“固定”的问题,通过延迟reloadData调用,直到用户完成滚动视图。 例如,创build一个包装的方法,而不是直接调用reloadData。

 - (void)updateData { if (self.collectionView.isTracking) { self.updateDataOnScrollingEnded = YES; } else { [self.collectionView reloadData]; } } 

然后当滚动结束时,从滚动视图的委托方法调用updateData方法(如果需要的话)。

 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { if (!decelerate) { [self scrollViewStopped:scrollView]; } } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { [self scrollViewStopped:scrollView]; } - (void)scrollViewStopped:(UIScrollView *)scrollView { if (self.updateDataOnScrollingEnded) { [self updateData]; self.updateDataOnScrollingEnded = NO; } } 

我的猜测是,在collectionView中某处存在一个弱点引用突出显示的单元格的indexPath,调用reload将释放该indexPath。 当collectionView然后试图取消注意单元格时,它崩溃。

编辑:

正如下面的评论所提到的,这个“解决scheme”有一些缺陷。 在进一步调查这个问题的时候,在我的情况下,这个问题似乎与在拖动收集视图期间在主线程上排队的多个reloadData调用有关。 当只有一个reloadData调用时,一切都很好,但是只要有一个以上 – 崩溃!

由于我总是只有一个部分在我的collectionView我用reloadData调用

 reloadSections:[NSIndexSet indexSetWithIndex:0] 

但是,这会导致单元格快速淡出并重新返回,这是我通过以下方法避免的(它可能更适合作为集合视图上的类别)

 - (void)reloadCollectionView:(UICollectionView *)collectionView animated:(BOOL)animated { [UIView setAnimationsEnabled:animated]; [collectionView performBatchUpdates:^{ [collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]]; } completion:^(BOOL finished) { [UIView setAnimationsEnabled:YES]; }]; } 

到目前为止,这对我来说工作得很好,它也允许在滚动时实际更新数据。

不确定后,只确定这段代码。 但是,碰撞信号(SIGSEGV)似乎是由于内存泄漏。 你只要去你的Xcode设置和编辑计划jsut启用僵尸选项,然后尝试重现您的崩溃。 它会显示Xcode控制台内的方法的控制器类名或任何崩溃相关的信息。 也只是尝试修改你的条件如下: –

 - (void)setHighlighted:(BOOL)highlighted { //just comment this line or write this line to the below and check //[super setHighlighted:highlighted]; if (highlighted) { self.alpha = 0.8; } else { self.alpha = 1.0; } [super setHighlighted:highlighted]; } 

我有这个问题,虽然有点不同的崩溃。 通过阻止任何重载数据直到突出显示被清除。 虽然toostn的build议可以解决这个问题,但能够在滚动时重新加载数据是有用的,但突出显示时没有什么意义 – 就像您手指放在单元格上一样。

实现以下UICollectionViewDelegate方法:

 - (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath { self.allowReload = NO; return YES; } - (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath { self.allowReload = YES; [self reloadIfNecessary]; // calls reloadData if it is necessary to do so! } 

我在一个集合视图的_unhighlightAllItems中也出现了这个崩溃,我使用了一个长按识别器来改变单元格的状态(但不是它们的数量),然后调用[collectionView reloadData] 。 就我而言,@toostn(使用performBatchUpdates )的解决scheme效果很好。

我也发现使用reloadItemsAtIndexPaths:而不是reloadData也可以避免崩溃。