UICollectionView crash on unhighlightAllItems

前端 未结 4 1057
别那么骄傲
别那么骄傲 2021-02-09 01:26

I\'ve gotten several crash reports related to a UICollectionView in iOS 7. I\'m not able to consistently recreate this crash.

Exception Type:  SIGSEGV
Exception         


        
4条回答
  •  南方客
    南方客 (楼主)
    2021-02-09 01:53

    If you are calling reloadData while the user is dragging the view, that might be the reason.

    I had crashes related to this with similar crash reports and "fixed" the issue by delaying the reloadData call until after the user has finished scrolling the view. E.g. create a wrapped method instead of calling reloadData directly.

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

    Then when scrolling ends, call the updateData method (if needed) from the scroll view's delegate methods.

    - (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;
         }
    }
    

    My guess is that there is a weak reference to the highlighted cell's indexPath somewhere inside of the collectionView, and that calling reload will dealloc that indexPath. When the collectionView then tries to unhighlight the cell, it crashes.

    EDIT:

    As mentioned in comments below, this "solution" has some flaws. While investigating the issue further, it seems that in my case the problem had to do with multiple reloadData calls being queued on the main thread during the dragging of the collection view. When there was only one reloadData call, everything was fine, but whenever there was more than one – crash!

    Since I always had exactly one section in my collectionView i replaced the reloadData call with

    reloadSections:[NSIndexSet indexSetWithIndex:0]
    

    However, this causes the cells to quickly fade out and back in again which I avoided with the following method (it would probably be better off as a category on the collection view)

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

    So far, this has worked well for me and it also allows for the data to actually be updated while scrolling.

提交回复
热议问题