From f72261bd103221cb3c21b150ecc554676475061b Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Mon, 16 May 2016 17:55:00 +0200 Subject: [PATCH 1/5] Remove comment and use sorted array for reloading data --- AsyncDisplayKit/Details/ASDataController.mm | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/AsyncDisplayKit/Details/ASDataController.mm b/AsyncDisplayKit/Details/ASDataController.mm index 44719f8652..4c1a41272b 100644 --- a/AsyncDisplayKit/Details/ASDataController.mm +++ b/AsyncDisplayKit/Details/ASDataController.mm @@ -815,8 +815,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; [_editingTransactionQueue waitUntilAllOperationsAreFinished]; - // sort indexPath in order to avoid messing up the index when deleting - // FIXME: Shouldn't deletes be sorted in descending order? + // sort indexPath in order to avoid messing up the index when deleting in several batches NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)]; [_editingTransactionQueue addOperationWithBlock:^{ @@ -838,14 +837,13 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; [self accessDataSourceWithBlock:^{ NSMutableArray *contexts = [[NSMutableArray alloc] initWithCapacity:indexPaths.count]; - // FIXME: This doesn't currently do anything - // FIXME: Shouldn't deletes be sorted in descending order? - [indexPaths sortedArrayUsingSelector:@selector(compare:)]; + // sort indexPath to avoid messing up the index when deleting + NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)]; id environment = [self.environmentDelegate dataControllerEnvironment]; ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection; - for (NSIndexPath *indexPath in indexPaths) { + for (NSIndexPath *indexPath in sortedIndexPaths) { ASCellNodeBlock nodeBlock = [_dataSource dataController:self nodeBlockAtIndexPath:indexPath]; ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:ASDataControllerRowNodeKind atIndexPath:indexPath]; [contexts addObject:[[ASIndexedNodeContext alloc] initWithNodeBlock:nodeBlock @@ -856,7 +854,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; [_editingTransactionQueue addOperationWithBlock:^{ LOG(@"Edit Transaction - reloadRows: %@", indexPaths); - [self _deleteNodesAtIndexPaths:indexPaths withAnimationOptions:animationOptions]; + [self _deleteNodesAtIndexPaths:sortedIndexPaths withAnimationOptions:animationOptions]; [self _batchLayoutNodesFromContexts:contexts withAnimationOptions:animationOptions]; }]; }]; From 45ff5634fe87926f9097fa5961545a58fe6dd45c Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Mon, 16 May 2016 17:55:23 +0200 Subject: [PATCH 2/5] Use NSFastEnumeration for enumerating though eyes of completedNodes --- AsyncDisplayKit/Details/ASDataController.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AsyncDisplayKit/Details/ASDataController.mm b/AsyncDisplayKit/Details/ASDataController.mm index 4c1a41272b..1c7b97b7bd 100644 --- a/AsyncDisplayKit/Details/ASDataController.mm +++ b/AsyncDisplayKit/Details/ASDataController.mm @@ -873,7 +873,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; // (see _layoutNodes:atIndexPaths:withAnimationOptions:). [_editingTransactionQueue addOperationWithBlock:^{ [_mainSerialQueue performBlockOnMainThread:^{ - for (NSString *kind in [_completedNodes keyEnumerator]) { + for (NSString *kind in _completedNodes) { [self _relayoutNodesOfKind:kind]; } }]; From 3e4b5e9e828ba066700c43d1ec82b2b68035990a Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Wed, 1 Jun 2016 10:33:53 -0700 Subject: [PATCH 3/5] Sort index paths or rows in descendant order for deletion --- AsyncDisplayKit/Details/ASDataController.mm | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/AsyncDisplayKit/Details/ASDataController.mm b/AsyncDisplayKit/Details/ASDataController.mm index 1c7b97b7bd..25cba537cc 100644 --- a/AsyncDisplayKit/Details/ASDataController.mm +++ b/AsyncDisplayKit/Details/ASDataController.mm @@ -782,7 +782,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; [_editingTransactionQueue waitUntilAllOperationsAreFinished]; - // sort indexPath to avoid messing up the index when inserting in several batches + // Sort indexPath to avoid messing up the index when inserting in several batches NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)]; NSMutableArray *contexts = [[NSMutableArray alloc] initWithCapacity:indexPaths.count]; @@ -815,8 +815,12 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; [_editingTransactionQueue waitUntilAllOperationsAreFinished]; - // sort indexPath in order to avoid messing up the index when deleting in several batches + // Sort indexPath in order to avoid messing up the index when deleting in several batches. NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)]; + + // When you delete at an index, you invalidate all subsequent indices, and we never want to use an invalid index + // in a later delete so we should have the sorted index path's array in descendent order + sortedIndexPaths = [[sortedIndexPaths reverseObjectEnumerator] allObjects]; [_editingTransactionQueue addOperationWithBlock:^{ LOG(@"Edit Transaction - deleteRows: %@", indexPaths); @@ -837,7 +841,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; [self accessDataSourceWithBlock:^{ NSMutableArray *contexts = [[NSMutableArray alloc] initWithCapacity:indexPaths.count]; - // sort indexPath to avoid messing up the index when deleting + // Sort indexPath to avoid messing up the index when deleting NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)]; id environment = [self.environmentDelegate dataControllerEnvironment]; @@ -851,10 +855,14 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; constrainedSize:constrainedSize environmentTraitCollection:environmentTraitCollection]]; } + + // When you delete at an index, you invalidate all subsequent indices, and we never want to use an invalid + // index in a later delete so we should have the sorted index path's array in descendent order + NSArray *reverseSortedIndexPaths = [[sortedIndexPaths reverseObjectEnumerator] allObjects]; [_editingTransactionQueue addOperationWithBlock:^{ LOG(@"Edit Transaction - reloadRows: %@", indexPaths); - [self _deleteNodesAtIndexPaths:sortedIndexPaths withAnimationOptions:animationOptions]; + [self _deleteNodesAtIndexPaths:reverseSortedIndexPaths withAnimationOptions:animationOptions]; [self _batchLayoutNodesFromContexts:contexts withAnimationOptions:animationOptions]; }]; }]; From 6566b7adb71660f0eda6a64fab5c92c3c6612644 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Wed, 1 Jun 2016 10:48:44 -0700 Subject: [PATCH 4/5] Use asdk_inverseCompare: to reverse sort the array of index path's to delete --- AsyncDisplayKit/Details/ASDataController.mm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/AsyncDisplayKit/Details/ASDataController.mm b/AsyncDisplayKit/Details/ASDataController.mm index 25cba537cc..756c9e0ed3 100644 --- a/AsyncDisplayKit/Details/ASDataController.mm +++ b/AsyncDisplayKit/Details/ASDataController.mm @@ -816,11 +816,9 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; [_editingTransactionQueue waitUntilAllOperationsAreFinished]; // Sort indexPath in order to avoid messing up the index when deleting in several batches. - NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)]; - // When you delete at an index, you invalidate all subsequent indices, and we never want to use an invalid index // in a later delete so we should have the sorted index path's array in descendent order - sortedIndexPaths = [[sortedIndexPaths reverseObjectEnumerator] allObjects]; + NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(asdk_inverseCompare:)]; [_editingTransactionQueue addOperationWithBlock:^{ LOG(@"Edit Transaction - deleteRows: %@", indexPaths); From 6945555d606c8a1c2045fbf5434389b1e5304cc7 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Wed, 1 Jun 2016 18:23:52 -0700 Subject: [PATCH 5/5] Sort in ascending order before removing nodes and restore FIXME --- AsyncDisplayKit/Details/ASDataController.mm | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/AsyncDisplayKit/Details/ASDataController.mm b/AsyncDisplayKit/Details/ASDataController.mm index 756c9e0ed3..af750bb4a2 100644 --- a/AsyncDisplayKit/Details/ASDataController.mm +++ b/AsyncDisplayKit/Details/ASDataController.mm @@ -816,9 +816,8 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; [_editingTransactionQueue waitUntilAllOperationsAreFinished]; // Sort indexPath in order to avoid messing up the index when deleting in several batches. - // When you delete at an index, you invalidate all subsequent indices, and we never want to use an invalid index - // in a later delete so we should have the sorted index path's array in descendent order - NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(asdk_inverseCompare:)]; + // FIXME: Shouldn't deletes be sorted in descending order? + NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)]; [_editingTransactionQueue addOperationWithBlock:^{ LOG(@"Edit Transaction - deleteRows: %@", indexPaths); @@ -840,6 +839,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; NSMutableArray *contexts = [[NSMutableArray alloc] initWithCapacity:indexPaths.count]; // Sort indexPath to avoid messing up the index when deleting + // FIXME: Shouldn't deletes be sorted in descending order? NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)]; id environment = [self.environmentDelegate dataControllerEnvironment]; @@ -854,13 +854,9 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; environmentTraitCollection:environmentTraitCollection]]; } - // When you delete at an index, you invalidate all subsequent indices, and we never want to use an invalid - // index in a later delete so we should have the sorted index path's array in descendent order - NSArray *reverseSortedIndexPaths = [[sortedIndexPaths reverseObjectEnumerator] allObjects]; - [_editingTransactionQueue addOperationWithBlock:^{ LOG(@"Edit Transaction - reloadRows: %@", indexPaths); - [self _deleteNodesAtIndexPaths:reverseSortedIndexPaths withAnimationOptions:animationOptions]; + [self _deleteNodesAtIndexPaths:sortedIndexPaths withAnimationOptions:animationOptions]; [self _batchLayoutNodesFromContexts:contexts withAnimationOptions:animationOptions]; }]; }];