如果您在用户拖动视图时调用 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 内部某处对突出显示的单元格的索引路径存在弱引用,并且调用重新加载将释放该索引路径。当 collectionView 尝试取消突出显示单元格时,它会崩溃。
EDIT:
正如下面的评论中提到的,这个“解决方案”有一些缺陷。在进一步调查该问题时,似乎在我的情况下,问题与拖动集合视图期间在主线程上排队的多个 reloadData 调用有关。当只有一个 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];
}];
}
到目前为止,这对我来说效果很好,并且它还允许在滚动时实际更新数据。