From 503b16fd620855a56b68f459536eba1dd04104f4 Mon Sep 17 00:00:00 2001 From: Victor Mayorov Date: Fri, 19 Jun 2015 12:37:38 +0300 Subject: [PATCH] Fixed crash on multiple -[ASTableView reloadData]. Implemented test. --- AsyncDisplayKit/Details/ASRangeController.mm | 26 +++---------- AsyncDisplayKitTests/ASTableViewTests.m | 39 ++++++++++++++++++++ 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/AsyncDisplayKit/Details/ASRangeController.mm b/AsyncDisplayKit/Details/ASRangeController.mm index 781b5974a5..44232dfe5d 100644 --- a/AsyncDisplayKit/Details/ASRangeController.mm +++ b/AsyncDisplayKit/Details/ASRangeController.mm @@ -21,7 +21,6 @@ // keys should be ASLayoutRangeTypes and values NSSets containing NSIndexPaths NSMutableDictionary *_rangeTypeIndexPaths; NSDictionary *_rangeTypeHandlers; - BOOL _queuedRangeUpdate; ASScrollDirection _scrollDirection; } @@ -68,25 +67,11 @@ - (void)visibleNodeIndexPathsDidChangeWithScrollDirection:(ASScrollDirection)scrollDirection { _scrollDirection = scrollDirection; - - if (_queuedRangeUpdate) { - return; - } - - // coalesce these events -- handling them multiple times per runloop is noisy and expensive - _queuedRangeUpdate = YES; - [self performSelector:@selector(updateVisibleNodeIndexPaths) - withObject:nil - afterDelay:0 - inModes:@[ NSRunLoopCommonModes ]]; + [self updateVisibleNodeIndexPaths]; } - (void)updateVisibleNodeIndexPaths { - if (!_queuedRangeUpdate) { - return; - } - NSArray *visibleNodePaths = [_delegate rangeControllerVisibleNodeIndexPaths:self]; NSSet *visibleNodePathsSet = [NSSet setWithArray:visibleNodePaths]; CGSize viewportSize = [_delegate rangeControllerViewportSize:self]; @@ -140,7 +125,6 @@ } _rangeIsValid = YES; - _queuedRangeUpdate = NO; } - (BOOL)shouldSkipVisibleNodesForRangeType:(ASLayoutRangeType)rangeType @@ -196,8 +180,8 @@ ASDisplayNodePerformBlockOnMainThread(^{ [_layoutController insertNodesAtIndexPaths:indexPaths withSizes:nodeSizes]; - [_delegate rangeController:self didInsertNodesAtIndexPaths:indexPaths withAnimationOption:animationOption]; _rangeIsValid = NO; + [_delegate rangeController:self didInsertNodesAtIndexPaths:indexPaths withAnimationOption:animationOption]; }); } @@ -212,8 +196,8 @@ - (void)dataController:(ASDataController *)dataController didDeleteNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption { ASDisplayNodePerformBlockOnMainThread(^{ [_layoutController deleteNodesAtIndexPaths:indexPaths]; - [_delegate rangeController:self didDeleteNodesAtIndexPaths:indexPaths withAnimationOption:animationOption]; _rangeIsValid = NO; + [_delegate rangeController:self didDeleteNodesAtIndexPaths:indexPaths withAnimationOption:animationOption]; }); } @@ -240,8 +224,8 @@ ASDisplayNodePerformBlockOnMainThread(^{ [_layoutController insertSections:sectionNodeSizes atIndexSet:indexSet]; - [_delegate rangeController:self didInsertSectionsAtIndexSet:indexSet withAnimationOption:animationOption]; _rangeIsValid = NO; + [_delegate rangeController:self didInsertSectionsAtIndexSet:indexSet withAnimationOption:animationOption]; }); } @@ -256,8 +240,8 @@ - (void)dataController:(ASDataController *)dataController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption { ASDisplayNodePerformBlockOnMainThread(^{ [_layoutController deleteSectionsAtIndexSet:indexSet]; - [_delegate rangeController:self didDeleteSectionsAtIndexSet:indexSet withAnimationOption:animationOption]; _rangeIsValid = NO; + [_delegate rangeController:self didDeleteSectionsAtIndexSet:indexSet withAnimationOption:animationOption]; }); } diff --git a/AsyncDisplayKitTests/ASTableViewTests.m b/AsyncDisplayKitTests/ASTableViewTests.m index 6275fc3370..8eb2d928ce 100644 --- a/AsyncDisplayKitTests/ASTableViewTests.m +++ b/AsyncDisplayKitTests/ASTableViewTests.m @@ -52,6 +52,27 @@ @end +@interface ASTableViewFilledDataSource : NSObject + +@end + +@implementation ASTableViewFilledDataSource + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return 100; +} + +- (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSIndexPath *)indexPath +{ + ASTextCellNode *textCellNode = [ASTextCellNode new]; + textCellNode.text = indexPath.description; + + return textCellNode; +} + +@end + @interface ASTableViewTests : XCTestCase @end @@ -83,4 +104,22 @@ XCTAssertTrue(tableViewDidDealloc, @"unexpected table view lifetime:%@", tableView); } +- (void)testReloadData +{ + ASTableView *tableView = [[ASTableView alloc] initWithFrame:CGRectMake(0, 0, 1000, 1000) + style:UITableViewStylePlain + asyncDataFetching:YES]; + + ASTableViewFilledDataSource *dataSource = [ASTableViewFilledDataSource new]; + + tableView.asyncDelegate = dataSource; + tableView.asyncDataSource = dataSource; + + for (int i = 0; i < 100; ++i) + { + [tableView reloadData]; + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; + } +} + @end