Fix Deleting Sections Issue (#2962)

* Add data source to main project

* Remove the idea of deletingSectionsOfKind – always delete all kinds

* Move comment into assertion
This commit is contained in:
Adlai Holler 2017-01-31 15:39:10 -08:00 committed by GitHub
parent 7f7f28385d
commit d7670780b2
4 changed files with 27 additions and 40 deletions

View File

@ -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 = "<group>"; };
CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASViewControllerTests.m; sourceTree = "<group>"; };
CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDisplayNodeSnapshotTests.m; sourceTree = "<group>"; };
CCBD05DE1E4147B000D18509 /* ASIGListAdapterBasedDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIGListAdapterBasedDataSource.m; sourceTree = "<group>"; };
CCBD05DF1E4147B000D18509 /* ASIGListAdapterBasedDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIGListAdapterBasedDataSource.h; sourceTree = "<group>"; };
CCE04B1E1E313EA7006AEBBB /* ASSectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASSectionController.h; sourceTree = "<group>"; };
CCE04B201E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "IGListAdapter+AsyncDisplayKit.h"; sourceTree = "<group>"; };
CCE04B211E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "IGListAdapter+AsyncDisplayKit.m"; sourceTree = "<group>"; };
@ -1839,6 +1846,8 @@
isa = PBXGroup;
children = (
CC6363E11E32C00800D8A8DE /* ASCollectionInteropProtocols.h */,
CCBD05DF1E4147B000D18509 /* ASIGListAdapterBasedDataSource.h */,
CCBD05DE1E4147B000D18509 /* ASIGListAdapterBasedDataSource.m */,
);
name = "Collection Data Adapter";
sourceTree = "<group>";
@ -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 */,

View File

@ -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<ASIndexedNodeContext *> * _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<NSIndexPath *> *)indexPaths

View File

@ -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<NSIndexPath *> *)indexPathsForEditingNodesOfKind:(NSString *)kind
{
NSArray *nodes = _editingNodes[kind];
return nodes != nil ? ASIndexPathsForTwoDimensionalArray(nodes) : nil;
}
- (NSMutableArray *)editingNodesOfKind:(NSString *)kind
{
return _editingNodes[kind] ? : [NSMutableArray array];

View File

@ -19,11 +19,6 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCellNode *> *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<NSIndexPath *> *)indexPathsForEditingNodesOfKind:(NSString *)kind;
/**
* Read-only access to the underlying editing nodes of the given kind
*/
@ -67,9 +62,9 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCellNode *> *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