如解决NSFetchedResultsController 和 UICollectionView一块儿使用时产生的崩溃

NSFetchedResultsController是一个很是好用且强大的数据库绑定类,用来处理CoreDataUIView的数据绑定很是便捷。前端

例如官方例子中,实用NSFetchedResultsController绑定UITableView,完成绑定后,开发者只要专一处理数据就好,UI会根据数据变化自动更新。数据库

而且NSFetchedResultsController还提供了缓存功能,大大提升了大数据量的CoreData检索效率。数组

然而这么好的东西,和UICollectionView并不能配合的很是默契。缓存

两个缘由:async

坑一

UICollectionView再也不有UITableView-(void)beginUpdates和`-(void)endUpdates`的方法,但却提供了一个使人尴尬的批量处理Cell的外包围方法大数据

- (void)performBatchUpdates:(void (^ __nullable)(void))updates completion:(void (^ __nullable)(BOOL finished))completion;

这个方法把操做包含到了block中执行,可是NSFetchedResultsController的UI改变通知回调是分四个回调方法完成的。因此我被迫使用了NSBlockOperation,把中间回调进行的操做包装到block中,再存到数组中,统一在atom

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller

中执行。但在当前页面删除cell时候仍是会报错。尴尬的我只好去掉了performBatchUpdates外包围,直接执行block,此次看起来没有问题了。spa

包装block的方法是这样线程

@property (nonatomic, strong) NSMutableArray* op;

[self.op addObject:[NSBlockOperation blockOperationWithBlock:^{
       [collectionView insertItemsAtIndexPaths:@[newIndexPath]];
}]];

执行block的方法是这样code

[self.op enumerateObjectsUsingBlock:^(NSBlockOperation*  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    [[NSOperationQueue mainQueue] addOperation:obj];
}];

坑二

第二个坑,是UICollectionView,并不能够在幕后之行insertdelete操做,会抛一个莫名其秒的异常。所谓幕后,就是UICollectionView的VC不是当前显示在最前端的VC,这种状况也是很常见的。

因此这个时候,要直接调用[collectionView reloadData]方法。
像这样

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    if (self.onTop) {
        [self.op enumerateObjectsUsingBlock:^(NSBlockOperation*  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [[NSOperationQueue mainQueue] addOperation:obj];
        }];
    }
    else
    {
        [self.collectionView reloadData];
    }
}

然而这一切仍是有问题,问题就出在,数据源上的数据量和执行insertItemsAtIndexPaths方法时的数据量不一样。

这就是performBatchUpdates方法存在的意义。

因此仍是须要用performBatchUpdatesblock住批量修改UI的代码,才能不报错。
而这个方法,必须在主线程执行。

dispatch_async(dispatch_get_main_queue(), ^{
        [self.collectionView performBatchUpdates:^{
        
        这里处理
}];
});

愿好运

相关文章
相关标签/搜索