Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions AsyncDisplayKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -950,10 +950,9 @@
058D09E1195D050800B7D73C /* Details */ = {
isa = PBXGroup;
children = (
25B171EA1C12242700508A7A /* Data Controller */,
CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */,
CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */,
251B8EF21BBB3D690087C538 /* ASCollectionDataController.h */,
251B8EF31BBB3D690087C538 /* ASCollectionDataController.mm */,
251B8EF41BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.h */,
251B8EF51BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m */,
251B8EF61BBB3D690087C538 /* ASDataController+Subclasses.h */,
Expand All @@ -969,10 +968,6 @@
299DA1A81A828D2900162D41 /* ASBatchContext.mm */,
205F0E1B1B373A2C007741D0 /* ASCollectionViewLayoutController.h */,
205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.mm */,
464052191A3F83C40061C0BA /* ASDataController.h */,
4640521A1A3F83C40061C0BA /* ASDataController.mm */,
AC026B671BD57D6F00BBC17E /* ASChangeSetDataController.h */,
AC026B681BD57D6F00BBC17E /* ASChangeSetDataController.m */,
05A6D05819D0EB64002DD95E /* ASDealloc2MainObject.h */,
05A6D05919D0EB64002DD95E /* ASDealloc2MainObject.m */,
4640521B1A3F83C40061C0BA /* ASFlowLayoutController.h */,
Expand Down Expand Up @@ -1110,6 +1105,19 @@
name = TextKit;
sourceTree = "<group>";
};
25B171EA1C12242700508A7A /* Data Controller */ = {
isa = PBXGroup;
children = (
251B8EF21BBB3D690087C538 /* ASCollectionDataController.h */,
251B8EF31BBB3D690087C538 /* ASCollectionDataController.mm */,
464052191A3F83C40061C0BA /* ASDataController.h */,
4640521A1A3F83C40061C0BA /* ASDataController.mm */,
AC026B671BD57D6F00BBC17E /* ASChangeSetDataController.h */,
AC026B681BD57D6F00BBC17E /* ASChangeSetDataController.m */,
);
name = "Data Controller";
sourceTree = "<group>";
};
AC6456051B0A333200CF11B8 /* Layout */ = {
isa = PBXGroup;
children = (
Expand Down
56 changes: 35 additions & 21 deletions AsyncDisplayKit/Details/ASCollectionDataController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,30 @@ @implementation ASCollectionDataController {
NSMutableDictionary *_pendingIndexPaths;
}

- (void)prepareForReloadData
- (instancetype)initWithAsyncDataFetching:(BOOL)asyncDataFetchingEnabled
{
_pendingNodes = [NSMutableDictionary dictionary];
_pendingIndexPaths = [NSMutableDictionary dictionary];
self = [super initWithAsyncDataFetching:asyncDataFetchingEnabled];
if (self != nil) {
_pendingNodes = [NSMutableDictionary dictionary];
_pendingIndexPaths = [NSMutableDictionary dictionary];
}
return self;
}

[[self supplementaryKinds] enumerateObjectsUsingBlock:^(NSString *kind, NSUInteger idx, BOOL *stop) {
- (void)prepareForReloadData
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this potentially get called multiple times, and need to recreate the _pendingNodes and _pendingIndexPaths dictionaries?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pending dictionaries exist to keep the pending state between the prepare and will methods. I've set them up to be created at initialization such that they'll remain throughout the lifetime of the collection data controller. Their contents are cleared out at the end of the will methods.

{
NSArray *kinds = [self supplementaryKinds];
for (NSString *kind in kinds) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for using fast enumeration! No need for block overhead. In this case I think it would be OK (although not much better) to call [self supplementaryKinds] in the for (), as it will only be called once.

LOG(@"Populating elements of kind: %@", kind);
NSMutableArray *indexPaths = [NSMutableArray array];
NSMutableArray *nodes = [NSMutableArray array];
[self _populateSupplementaryNodesOfKind:kind withMutableNodes:nodes mutableIndexPaths:indexPaths];
_pendingNodes[kind] = nodes;
_pendingIndexPaths[kind] = indexPaths;

// Measure loaded nodes before leaving the main thread
[self layoutLoadedNodes:nodes ofKind:kind atIndexPaths:indexPaths];
}];
}
}

- (void)willReloadData
Expand All @@ -56,7 +64,7 @@ - (void)willReloadData
NSArray *editingNodes = [self editingNodesOfKind:kind];
NSMutableIndexSet *indexSet = [[NSMutableIndexSet alloc] initWithIndexesInRange:NSMakeRange(0, editingNodes.count)];
[self deleteSectionsOfKind:kind atIndexSet:indexSet completion:nil];

// Insert each section
NSUInteger sectionCount = [self.collectionDataSource dataController:self numberOfSectionsForSupplementaryNodeOfKind:kind];
NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
Expand All @@ -75,7 +83,8 @@ - (void)willReloadData

- (void)prepareForInsertSections:(NSIndexSet *)sections
{
[[self supplementaryKinds] enumerateObjectsUsingBlock:^(NSString *kind, NSUInteger idx, BOOL *stop) {
NSArray *kinds = [self supplementaryKinds];
for (NSString *kind in kinds) {
LOG(@"Populating elements of kind: %@, for sections: %@", kind, sections);
NSMutableArray *nodes = [NSMutableArray array];
NSMutableArray *indexPaths = [NSMutableArray array];
Expand All @@ -85,7 +94,7 @@ - (void)prepareForInsertSections:(NSIndexSet *)sections

// Measure loaded nodes before leaving the main thread
[self layoutLoadedNodes:nodes ofKind:kind atIndexPaths:indexPaths];
}];
}
}

- (void)willInsertSections:(NSIndexSet *)sections
Expand All @@ -97,25 +106,29 @@ - (void)willInsertSections:(NSIndexSet *)sections
}

[self insertSections:sectionArray ofKind:kind atIndexSet:sections completion:nil];
[self batchLayoutNodes:nodes ofKind:kind atIndexPaths:_pendingIndexPaths[kind] completion:nil];
_pendingNodes[kind] = nil;
_pendingIndexPaths[kind] = nil;
[self batchLayoutNodes:nodes ofKind:kind atIndexPaths:_pendingIndexPaths[kind] completion:^(NSArray *nodes, NSArray *indexPaths) {
[self insertNodes:nodes ofKind:kind atIndexPaths:indexPaths completion:nil];
}];
[_pendingNodes removeObjectForKey:kind];
[_pendingIndexPaths removeObjectForKey:kind];
}];
}

- (void)willDeleteSections:(NSIndexSet *)sections
{
[[self supplementaryKinds] enumerateObjectsUsingBlock:^(NSString *kind, NSUInteger idx, BOOL *stop) {
NSArray *kinds = [self supplementaryKinds];
for (NSString *kind in kinds) {
NSArray *indexPaths = ASIndexPathsForMultidimensionalArrayAtIndexSet([self editingNodesOfKind:kind], sections);

[self deleteNodesOfKind:kind atIndexPaths:indexPaths completion:nil];
[self deleteSectionsOfKind:kind atIndexSet:sections completion:nil];
}];
}
}

- (void)prepareForReloadSections:(NSIndexSet *)sections
{
[[self supplementaryKinds] enumerateObjectsUsingBlock:^(NSString *kind, NSUInteger idx, BOOL *stop) {
NSArray *kinds = [self supplementaryKinds];
for (NSString *kind in kinds) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I see you did the whole file - which is badass!! - it probably would be better to save the lines and do the self call inline with the for ().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup good idea.

NSMutableArray *nodes = [NSMutableArray array];
NSMutableArray *indexPaths = [NSMutableArray array];
[self _populateSupplementaryNodesOfKind:kind withSections:sections mutableNodes:nodes mutableIndexPaths:indexPaths];
Expand All @@ -124,7 +137,7 @@ - (void)prepareForReloadSections:(NSIndexSet *)sections

// Measure loaded nodes before leaving the main thread
[self layoutLoadedNodes:nodes ofKind:kind atIndexPaths:indexPaths];
}];
}
}

- (void)willReloadSections:(NSIndexSet *)sections
Expand All @@ -134,14 +147,15 @@ - (void)willReloadSections:(NSIndexSet *)sections
[self deleteNodesOfKind:kind atIndexPaths:indexPaths completion:nil];
// reinsert the elements
[self batchLayoutNodes:nodes ofKind:kind atIndexPaths:_pendingIndexPaths[kind] completion:nil];
_pendingNodes[kind] = nil;
_pendingIndexPaths[kind] = nil;
[_pendingNodes removeObjectForKey:kind];
[_pendingIndexPaths removeObjectForKey:kind];
}];
}

- (void)willMoveSection:(NSInteger)section toSection:(NSInteger)newSection
{
[[self supplementaryKinds] enumerateObjectsUsingBlock:^(NSString *kind, NSUInteger idx, BOOL *stop) {
NSArray *kinds = [self supplementaryKinds];
for (NSString *kind in kinds) {
NSArray *indexPaths = ASIndexPathsForMultidimensionalArrayAtIndexSet([self editingNodesOfKind:kind], [NSIndexSet indexSetWithIndex:section]);
NSArray *nodes = ASFindElementsInMultidimensionalArrayAtIndexPaths([self editingNodesOfKind:kind], indexPaths);
[self deleteNodesOfKind:kind atIndexPaths:indexPaths completion:nil];
Expand All @@ -153,7 +167,7 @@ - (void)willMoveSection:(NSInteger)section toSection:(NSInteger)newSection
[updatedIndexPaths addObject:[sectionIndexPath indexPathByAddingIndex:[indexPath indexAtPosition:indexPath.length - 1]]];
}];
[self insertNodes:nodes ofKind:kind atIndexPaths:indexPaths completion:nil];
}];
}
}

- (void)_populateSupplementaryNodesOfKind:(NSString *)kind withMutableNodes:(NSMutableArray *)nodes mutableIndexPaths:(NSMutableArray *)indexPaths
Expand Down Expand Up @@ -214,4 +228,4 @@ - (NSArray *)supplementaryKinds
return (id<ASCollectionDataControllerSource>)self.dataSource;
}

@end
@end