From 28cfd60900bdedd1034ef25b775d1b314f9f2254 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Tue, 26 Apr 2016 10:37:06 -0700 Subject: [PATCH] Fix Assertion on cell deallocation due visibility not being cleared Further information: - We mark every node as visible in the ASRangeController which NSIndexPath is returned from visibleNodeIndexPathsForRangeController: - In visibleNodeIndexPathsForRangeController: we get the visible index path's via a call to UITableView's "indexPathsForVisibleRows" method. - Unfortunately in this case we cannot use indexPathsForVisibleRows to get all the visible index paths as apparently in a grouped UITableView it would return index paths for cells that are just a bit over the edge of the visible area. - But this edge cells will never get a call for -tableView:cellForRowAtIndexPath:, but we will mark them as visible in the range controller - In tableView:cellForRowAtIndexPath: we call -configureContentView:forCellNode - Because we never get a -configureContentView:forCellNode call for the edge cells, the _ASDisplayView of the nodes will never be added to the window and get a willMoveToWindow and didMoveToWindow call and it's never get's added to the window for now and so the node is NOT marked as "in the hirarchy" - If the deallocation of the views are happening without the UITableView ever scrolled, the cells don't get a call to __exitHierarchy as they were never added to the window and stay in the interface state "visible" and an exception will be raised within the dealloc method of the ASDisplayNode --- AsyncDisplayKit/ASTableView.mm | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/AsyncDisplayKit/ASTableView.mm b/AsyncDisplayKit/ASTableView.mm index 5fe3d06694..dfd7c6353e 100644 --- a/AsyncDisplayKit/ASTableView.mm +++ b/AsyncDisplayKit/ASTableView.mm @@ -818,10 +818,17 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; return @[]; } - NSArray *visibleIndexPaths = self.indexPathsForVisibleRows; + // In this case we cannot use indexPathsForVisibleRows in this case to get all the visible index paths as apparently + // in a grouped UITableView it would return index paths for cells that are over the edge of the visible area. + // Unfortunatly this means we never get a call for -tableView:cellForRowAtIndexPath: for that cells, but we will mark + // mark them as visible in the range controller + NSMutableArray *visibleIndexPaths = [NSMutableArray array]; + for (id cell in self.visibleCells) { + [visibleIndexPaths addObject:[self indexPathForCell:cell]]; + } if (_pendingVisibleIndexPath) { - NSMutableSet *indexPaths = [NSMutableSet setWithArray:self.indexPathsForVisibleRows]; + NSMutableSet *indexPaths = [NSMutableSet setWithArray:visibleIndexPaths]; BOOL (^isAfter)(NSIndexPath *, NSIndexPath *) = ^BOOL(NSIndexPath *indexPath, NSIndexPath *anchor) { if (!anchor || !indexPath) { @@ -857,7 +864,9 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; _pendingVisibleIndexPath = nil; // not contiguous, ignore. } else { [indexPaths addObject:_pendingVisibleIndexPath]; - visibleIndexPaths = [indexPaths.allObjects sortedArrayUsingSelector:@selector(compare:)]; + + [visibleIndexPaths removeAllObjects]; + [visibleIndexPaths addObjectsFromArray:[indexPaths.allObjects sortedArrayUsingSelector:@selector(compare:)]]; } }