diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 2844d385cb..94b222ae95 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -477,6 +477,10 @@ CC8B05D81D73979700F54286 /* ASTextNodePerformanceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8B05D71D73979700F54286 /* ASTextNodePerformanceTests.m */; }; CCA221D31D6FA7EF00AF6A0F /* ASViewControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.m */; }; CCB2F34D1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m */; }; + CCBD05E01E4147B000D18509 /* ASIGListAdapterBasedDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = CCBD05DE1E4147B000D18509 /* ASIGListAdapterBasedDataSource.m */; }; + CCBD05E11E4147B000D18509 /* ASIGListAdapterBasedDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = CCBD05DE1E4147B000D18509 /* ASIGListAdapterBasedDataSource.m */; }; + CCBD05E21E4147B000D18509 /* ASIGListAdapterBasedDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = CCBD05DF1E4147B000D18509 /* ASIGListAdapterBasedDataSource.h */; }; + CCBD05E31E4147CC00D18509 /* ASIGListAdapterBasedDataSource.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CCBD05DF1E4147B000D18509 /* ASIGListAdapterBasedDataSource.h */; }; CCE04B1F1E313EA7006AEBBB /* ASSectionController.h in Headers */ = {isa = PBXBuildFile; fileRef = CCE04B1E1E313EA7006AEBBB /* ASSectionController.h */; settings = {ATTRIBUTES = (Public, ); }; }; CCE04B221E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = CCE04B201E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.h */; }; CCE04B231E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE04B211E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.m */; }; @@ -693,6 +697,7 @@ dstPath = "include/$(PRODUCT_NAME)"; dstSubfolderSpec = 16; files = ( + CCBD05E31E4147CC00D18509 /* ASIGListAdapterBasedDataSource.h in CopyFiles */, CC8525181E3FC316008EABE6 /* _ASCollectionViewCell.h in CopyFiles */, 80364CC71E3D89410094400C /* ASNodeController.h in CopyFiles */, 690ED59D1E36D140000627C0 /* ASImageNode+tvOS.h in CopyFiles */, @@ -1197,6 +1202,8 @@ CC8B05D71D73979700F54286 /* ASTextNodePerformanceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTextNodePerformanceTests.m; sourceTree = ""; }; CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASViewControllerTests.m; sourceTree = ""; }; CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDisplayNodeSnapshotTests.m; sourceTree = ""; }; + CCBD05DE1E4147B000D18509 /* ASIGListAdapterBasedDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIGListAdapterBasedDataSource.m; sourceTree = ""; }; + CCBD05DF1E4147B000D18509 /* ASIGListAdapterBasedDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIGListAdapterBasedDataSource.h; sourceTree = ""; }; CCE04B1E1E313EA7006AEBBB /* ASSectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASSectionController.h; sourceTree = ""; }; CCE04B201E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "IGListAdapter+AsyncDisplayKit.h"; sourceTree = ""; }; CCE04B211E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "IGListAdapter+AsyncDisplayKit.m"; sourceTree = ""; }; @@ -1839,6 +1846,8 @@ isa = PBXGroup; children = ( CC6363E11E32C00800D8A8DE /* ASCollectionInteropProtocols.h */, + CCBD05DF1E4147B000D18509 /* ASIGListAdapterBasedDataSource.h */, + CCBD05DE1E4147B000D18509 /* ASIGListAdapterBasedDataSource.m */, ); name = "Collection Data Adapter"; sourceTree = ""; @@ -2024,6 +2033,7 @@ 83A7D95C1D44548100BF333E /* ASWeakMap.h in Headers */, 69708BA61D76386D005C3CF9 /* ASEqualityHashHelpers.h in Headers */, B350622D1B010EFD0018CF92 /* ASScrollDirection.h in Headers */, + CCBD05E21E4147B000D18509 /* ASIGListAdapterBasedDataSource.h in Headers */, 254C6B751BF94DF4003EC431 /* ASTextKitComponents.h in Headers */, B35062081B010EFD0018CF92 /* ASScrollNode.h in Headers */, 25E327571C16819500A2170C /* ASPagerNode.h in Headers */, @@ -2283,6 +2293,7 @@ DBDB83961C6E879900D0098C /* ASPagerFlowLayout.m in Sources */, 058D0A26195D050800B7D73C /* _ASCoreAnimationExtras.mm in Sources */, 6947B0C41E36B5040007C478 /* ASStackPositionedLayout.mm in Sources */, + CCBD05E01E4147B000D18509 /* ASIGListAdapterBasedDataSource.m in Sources */, 257754B41BEE44CD00737CA5 /* ASTextKitTailTruncater.mm in Sources */, 68B8A4E31CBDB958007E4543 /* ASWeakProxy.m in Sources */, 69E1006F1CA89CB600D88C1B /* ASEnvironmentInternal.mm in Sources */, @@ -2477,6 +2488,7 @@ 9B92C8851BC2EB6E00EE46B2 /* ASCollectionDataController.mm in Sources */, B350623D1B010EFD0018CF92 /* _ASAsyncTransaction.mm in Sources */, 6947B0C51E36B5040007C478 /* ASStackPositionedLayout.mm in Sources */, + CCBD05E11E4147B000D18509 /* ASIGListAdapterBasedDataSource.m in Sources */, B35062401B010EFD0018CF92 /* _ASAsyncTransactionContainer.m in Sources */, AC026B721BD57DBF00BBC17E /* _ASHierarchyChangeSet.mm in Sources */, B35062421B010EFD0018CF92 /* _ASAsyncTransactionGroup.m in Sources */, diff --git a/AsyncDisplayKit/Details/ASCollectionDataController.mm b/AsyncDisplayKit/Details/ASCollectionDataController.mm index b56333a753..3263af7a5b 100644 --- a/AsyncDisplayKit/Details/ASCollectionDataController.mm +++ b/AsyncDisplayKit/Details/ASCollectionDataController.mm @@ -81,15 +81,10 @@ [self applyPendingSections:sectionIndexes]; + // Assert that ASDataController has already deleted all the old sections for us. + ASDisplayNodeAssert([self editingNodesOfKind:ASDataControllerRowNodeKind].count == 0, @"Expected that all old sections were deleted before %@. Sections: %@", NSStringFromSelector(_cmd), [self editingNodesOfKind:ASDataControllerRowNodeKind]); + [_pendingNodeContexts enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull kind, NSMutableArray * _Nonnull contexts, __unused BOOL * _Nonnull stop) { - // Remove everything that existed before the reload, now that we're ready to insert replacements - NSArray *indexPaths = [self indexPathsForEditingNodesOfKind:kind]; - [self deleteNodesOfKind:kind atIndexPaths:indexPaths completion:nil]; - - NSArray *editingNodes = [self editingNodesOfKind:kind]; - NSIndexSet *indexSet = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(0, editingNodes.count)]; - [self deleteSectionsOfKind:kind atIndexSet:indexSet completion:nil]; - // Insert each section NSMutableArray *sections = [NSMutableArray arrayWithCapacity:newSectionCount]; for (int i = 0; i < newSectionCount; i++) { @@ -135,22 +130,9 @@ [_pendingNodeContexts removeAllObjects]; } -- (void)prepareForDeleteSections:(NSIndexSet *)sections -{ - _supplementaryKindsForPendingOperation = [self supplementaryKindsInSections:sections]; -} - - (void)willDeleteSections:(NSIndexSet *)sections { [_sections removeObjectsAtIndexes:sections]; - - for (NSString *kind in _supplementaryKindsForPendingOperation) { - NSArray *indexPaths = ASIndexPathsForMultidimensionalArrayAtIndexSet([self editingNodesOfKind:kind], sections); - - [self deleteNodesOfKind:kind atIndexPaths:indexPaths completion:nil]; - [self deleteSectionsOfKind:kind atIndexSet:sections completion:nil]; - } - _supplementaryKindsForPendingOperation = nil; } - (void)prepareForInsertRowsAtIndexPaths:(NSArray *)indexPaths diff --git a/AsyncDisplayKit/Details/ASDataController.mm b/AsyncDisplayKit/Details/ASDataController.mm index eafe89ea9b..0d6ae4abae 100644 --- a/AsyncDisplayKit/Details/ASDataController.mm +++ b/AsyncDisplayKit/Details/ASDataController.mm @@ -308,18 +308,22 @@ NSString * const ASCollectionInvalidUpdateException = @"ASCollectionInvalidUpdat }]; } -- (void)deleteSectionsOfKind:(NSString *)kind atIndexSet:(NSIndexSet *)indexSet completion:(void (^)(NSIndexSet *indexSet))completionBlock +- (void)deleteSections:(NSIndexSet *)indexSet completion:(void (^)())completionBlock { ASSERT_ON_EDITING_QUEUE; if (!indexSet.count || _dataSource == nil) { return; } - - [_editingNodes[kind] removeObjectsAtIndexes:indexSet]; + + [_editingNodes enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull kind, NSMutableArray *sections, BOOL * _Nonnull stop) { + [sections removeObjectsAtIndexes:indexSet]; + }]; [_mainSerialQueue performBlockOnMainThread:^{ - [_completedNodes[kind] removeObjectsAtIndexes:indexSet]; + [_completedNodes enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull kind, NSMutableArray *sections, BOOL * _Nonnull stop) { + [sections removeObjectsAtIndexes:indexSet]; + }]; if (completionBlock) { - completionBlock(indexSet); + completionBlock(); } }]; } @@ -390,7 +394,7 @@ NSString * const ASCollectionInvalidUpdateException = @"ASCollectionInvalidUpdat { ASSERT_ON_EDITING_QUEUE; - [self deleteSectionsOfKind:ASDataControllerRowNodeKind atIndexSet:indexSet completion:^(NSIndexSet *indexSet) { + [self deleteSections:indexSet completion:^() { ASDisplayNodeAssertMainThread(); if (_delegateDidDeleteSections) @@ -899,12 +903,6 @@ NSString * const ASCollectionInvalidUpdateException = @"ASCollectionInvalidUpdat #pragma mark - Data Querying (Subclass API) -- (NSArray *)indexPathsForEditingNodesOfKind:(NSString *)kind -{ - NSArray *nodes = _editingNodes[kind]; - return nodes != nil ? ASIndexPathsForTwoDimensionalArray(nodes) : nil; -} - - (NSMutableArray *)editingNodesOfKind:(NSString *)kind { return _editingNodes[kind] ? : [NSMutableArray array]; diff --git a/AsyncDisplayKit/Private/ASDataController+Subclasses.h b/AsyncDisplayKit/Private/ASDataController+Subclasses.h index 141ce0c9f7..edd7872910 100644 --- a/AsyncDisplayKit/Private/ASDataController+Subclasses.h +++ b/AsyncDisplayKit/Private/ASDataController+Subclasses.h @@ -19,11 +19,6 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray *nodes, NS #pragma mark - Internal editing & completed store querying -/** - * Provides a collection of index paths for nodes of the given kind that are currently in the editing store - */ -- (NSArray *)indexPathsForEditingNodesOfKind:(NSString *)kind; - /** * Read-only access to the underlying editing nodes of the given kind */ @@ -67,9 +62,9 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray *nodes, NS - (void)insertSections:(NSMutableArray *)sections ofKind:(NSString *)kind atIndexSet:(NSIndexSet *)indexSet completion:(void (^)(NSArray *sections, NSIndexSet *indexSet))completionBlock; /** - * Deletes the given sections of the specified kind in the backing store, calling completion on the main thread when finished. + * Deletes the given sections in the backing store, calling completion on the main thread when finished. */ -- (void)deleteSectionsOfKind:(NSString *)kind atIndexSet:(NSIndexSet *)indexSet completion:(void (^)(NSIndexSet *indexSet))completionBlock; +- (void)deleteSections:(NSIndexSet *)indexSet completion:(void (^)())completionBlock; #pragma mark - Data Manipulation Hooks