diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index 64c28d5806..0835dcfbe1 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -755,8 +755,13 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; } } -- (void)_scheduleCheckForBatchFetching +- (void)_scheduleCheckForBatchFetchingForNumberOfChanges:(NSUInteger)changes { + // Prevent fetching will continually trigger in a loop after reaching end of content and no new content was provided + if (changes == 0) { + return; + } + // Push this to the next runloop to be sure the scroll view has the right content size dispatch_async(dispatch_get_main_queue(), ^{ [self _checkForBatchFetching]; @@ -973,6 +978,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes } + NSUInteger numberOfUpdateBlocks = _batchUpdateBlocks.count; ASPerformBlockWithoutAnimation(!animated, ^{ [_layoutFacilitator collectionViewWillPerformBatchUpdates]; [super performBatchUpdates:^{ @@ -980,7 +986,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; block(); } } completion:^(BOOL finished){ - [self _scheduleCheckForBatchFetching]; + [self _scheduleCheckForBatchFetchingForNumberOfChanges:numberOfUpdateBlocks]; if (completion) { completion(finished); } }]; }); @@ -1005,7 +1011,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; [_layoutFacilitator collectionViewWillEditCellsAtIndexPaths:indexPaths batched:NO]; [UIView performWithoutAnimation:^{ [super insertItemsAtIndexPaths:indexPaths]; - [self _scheduleCheckForBatchFetching]; + [self _scheduleCheckForBatchFetchingForNumberOfChanges:indexPaths.count]; }]; } } @@ -1026,7 +1032,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; [_layoutFacilitator collectionViewWillEditCellsAtIndexPaths:indexPaths batched:NO]; [UIView performWithoutAnimation:^{ [super deleteItemsAtIndexPaths:indexPaths]; - [self _scheduleCheckForBatchFetching]; + [self _scheduleCheckForBatchFetchingForNumberOfChanges:indexPaths.count]; }]; } } @@ -1047,7 +1053,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; [_layoutFacilitator collectionViewWillEditSectionsAtIndexSet:indexSet batched:NO]; [UIView performWithoutAnimation:^{ [super insertSections:indexSet]; - [self _scheduleCheckForBatchFetching]; + [self _scheduleCheckForBatchFetchingForNumberOfChanges:indexSet.count]; }]; } } @@ -1068,7 +1074,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; [_layoutFacilitator collectionViewWillEditSectionsAtIndexSet:indexSet batched:NO]; [UIView performWithoutAnimation:^{ [super deleteSections:indexSet]; - [self _scheduleCheckForBatchFetching]; + [self _scheduleCheckForBatchFetchingForNumberOfChanges:indexSet.count]; }]; } } diff --git a/AsyncDisplayKit/ASTableView.mm b/AsyncDisplayKit/ASTableView.mm index 1a37208416..6718932297 100644 --- a/AsyncDisplayKit/ASTableView.mm +++ b/AsyncDisplayKit/ASTableView.mm @@ -730,8 +730,13 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; } } -- (void)_scheduleCheckForBatchFetching +- (void)_scheduleCheckForBatchFetchingForNumberOfChanges:(NSUInteger)changes { + // Prevent fetching will continually trigger in a loop after reaching end of content and no new content was provided + if (changes == 0) { + return; + } + // Push this to the next runloop to be sure the scroll view has the right content size dispatch_async(dispatch_get_main_queue(), ^{ [self _checkForBatchFetching]; @@ -904,7 +909,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; BOOL preventAnimation = animationOptions == UITableViewRowAnimationNone; ASPerformBlockWithoutAnimation(preventAnimation, ^{ [super insertRowsAtIndexPaths:indexPaths withRowAnimation:(UITableViewRowAnimation)animationOptions]; - [self _scheduleCheckForBatchFetching]; + [self _scheduleCheckForBatchFetchingForNumberOfChanges:indexPaths.count]; }); if (_automaticallyAdjustsContentOffset) { @@ -924,7 +929,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; BOOL preventAnimation = animationOptions == UITableViewRowAnimationNone; ASPerformBlockWithoutAnimation(preventAnimation, ^{ [super deleteRowsAtIndexPaths:indexPaths withRowAnimation:(UITableViewRowAnimation)animationOptions]; - [self _scheduleCheckForBatchFetching]; + [self _scheduleCheckForBatchFetchingForNumberOfChanges:indexPaths.count]; }); if (_automaticallyAdjustsContentOffset) { @@ -945,7 +950,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; BOOL preventAnimation = animationOptions == UITableViewRowAnimationNone; ASPerformBlockWithoutAnimation(preventAnimation, ^{ [super insertSections:indexSet withRowAnimation:(UITableViewRowAnimation)animationOptions]; - [self _scheduleCheckForBatchFetching]; + [self _scheduleCheckForBatchFetchingForNumberOfChanges:indexSet.count]; }); } @@ -961,7 +966,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; BOOL preventAnimation = animationOptions == UITableViewRowAnimationNone; ASPerformBlockWithoutAnimation(preventAnimation, ^{ [super deleteSections:indexSet withRowAnimation:(UITableViewRowAnimation)animationOptions]; - [self _scheduleCheckForBatchFetching]; + [self _scheduleCheckForBatchFetchingForNumberOfChanges:indexSet.count]; }); }