[英]UICollectionView crash on unhighlightAllItems
我收到了几个与iOS 7中的UICollectionView相关的崩溃报告。我无法一致地重新创建这个崩溃。
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共享一个管理突出显示的公共超类。 当单元格突出显示时,alpha会发生变化。
- (void)setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
if (highlighted) {
self.alpha = 0.8;
} else {
self.alpha = 1.0;
}
}
可以调用[super setHighlighted:highlight]导致这样的崩溃吗? 该应用程序是使用XCode 4编译和提交的,并且仅在iOS 7上发生。还有任何其他建议可以确定这种情况发生的位置。 谢谢你的帮助。
编辑:我能够在调试器中捕获它,但它仍然不能始终如一地重现。 崩溃是:
[NSIndexPath section] message sent to deallocated instance XXXXXXXX
如果在用户拖动视图时调用reloadData,则可能是原因。
我通过类似的崩溃报告与此相关的崩溃,并通过延迟reloadData调用“修复”问题,直到用户完成滚动视图。 例如,创建一个包装方法,而不是直接调用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尝试取消突出显示单元格时,它会崩溃。
编辑:
正如下面的评论所述,这种“解决方案”存在一些缺陷。 在进一步研究这个问题时,似乎在我的情况下,问题与在拖动集合视图期间在主线程上排队的多个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设置,然后在Edit Scheme中启用jsut启用Zombie选项,然后尝试重现您的崩溃。 它将显示方法的控制器类名称或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];
}
我有这个问题,但崩溃略有不同。 通过保持任何reloadData来修复,直到高亮显示被清除。 虽然toostn的建议可以解决这个问题,但是在滚动时能够重新加载数据是有用的,但在突出显示时没有多大意义 - 因为你手指放在一个单元格上。
实现以下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
)效果很好。
我还发现使用reloadItemsAtIndexPaths:
而不是reloadData
也可以避免崩溃。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.