如解決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:^{
        
        這裏處理
}];
});

願好運

相關文章
相關標籤/搜索