diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index 36a995f90b..ee9648cdc7 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -543,6 +543,13 @@ static BOOL _isInterceptedSelector(SEL sel) - (void)rangeControllerEndUpdates:(ASRangeController *)rangeController completion:(void (^)(BOOL))completion { ASDisplayNodeAssertMainThread(); + if (!self.asyncDataSource) { + if (completion) { + completion(NO); + } + return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes + } + [super performBatchUpdates:^{ [_batchUpdateBlocks enumerateObjectsUsingBlock:^(dispatch_block_t block, NSUInteger idx, BOOL *stop) { block(); @@ -577,6 +584,11 @@ static BOOL _isInterceptedSelector(SEL sel) - (void)rangeController:(ASRangeController *)rangeController didInsertNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions { ASDisplayNodeAssertMainThread(); + + if (!self.asyncDataSource) { + return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes + } + if (_performingBatchUpdates) { [_batchUpdateBlocks addObject:^{ [super insertItemsAtIndexPaths:indexPaths]; @@ -592,6 +604,10 @@ static BOOL _isInterceptedSelector(SEL sel) { ASDisplayNodeAssertMainThread(); + if (!self.asyncDataSource) { + return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes + } + if (_performingBatchUpdates) { [_batchUpdateBlocks addObject:^{ [super deleteItemsAtIndexPaths:indexPaths]; @@ -607,6 +623,10 @@ static BOOL _isInterceptedSelector(SEL sel) { ASDisplayNodeAssertMainThread(); + if (!self.asyncDataSource) { + return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes + } + if (_performingBatchUpdates) { [_batchUpdateBlocks addObject:^{ [super insertSections:indexSet]; @@ -622,6 +642,10 @@ static BOOL _isInterceptedSelector(SEL sel) { ASDisplayNodeAssertMainThread(); + if (!self.asyncDataSource) { + return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes + } + if (_performingBatchUpdates) { [_batchUpdateBlocks addObject:^{ [super deleteSections:indexSet];