ASDataController improvements

- _populateFromDataSourceWithSectionIndexSet doesn't accept a mutanle array but allocate one itself.
- Remove _populateFromEntireDataSourceWithMutableContexts.
- ASIndexedNodeContext executes its block, nil out the block and return the result.
This commit is contained in:
Huy Nguyen 2016-02-29 14:03:32 -08:00
parent b098d80796
commit 6d463daac7
3 changed files with 31 additions and 40 deletions

View File

@ -178,9 +178,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(batchCount, queue, ^(size_t i) {
unsigned long k = j + i;
ASIndexedNodeContext *context = contexts[k];
ASCellNodeBlock nodeBlock = context.nodeBlock;
ASCellNode *node = nodeBlock();
ASCellNode *node = [contexts[k] allocateNode];
ASDisplayNodeAssertNotNil(node, @"Node block created nil node");
allocatedNodeBuffer[i] = node;
});
@ -422,8 +420,8 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
[self accessDataSourceSynchronously:synchronously withBlock:^{
NSUInteger sectionCount = [_dataSource numberOfSectionsInDataController:self];
NSMutableArray<ASIndexedNodeContext *> *contexts = [NSMutableArray array];
[self _populateFromEntireDataSourceWithMutableContexts:contexts];
NSIndexSet *sectionIndexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, sectionCount)];
NSArray<ASIndexedNodeContext *> *contexts = [self _populateFromDataSourceWithSectionIndexSet:sectionIndexSet];
// Allow subclasses to perform setup before going into the edit transaction
[self prepareForReloadData];
@ -441,13 +439,12 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
[self willReloadData];
// Insert each section
// Insert empty sections
NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
for (int i = 0; i < sectionCount; i++) {
[sections addObject:[[NSMutableArray alloc] init]];
}
[self _insertSections:sections atIndexSet:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, sectionCount)] withAnimationOptions:animationOptions];
[self _insertSections:sections atIndexSet:sectionIndexSet withAnimationOptions:animationOptions];
[self _batchLayoutNodesFromContexts:contexts withAnimationOptions:animationOptions];
@ -494,11 +491,10 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
/**
* Fetches row contexts for the provided sections from the data source.
*
* @discussion Results are stored in the passed mutable arrays.
*/
- (void)_populateFromDataSourceWithSectionIndexSet:(NSIndexSet *)indexSet mutableContexts:(NSMutableArray<ASIndexedNodeContext *> *)contexts
- (NSArray<ASIndexedNodeContext *> *)_populateFromDataSourceWithSectionIndexSet:(NSIndexSet *)indexSet
{
NSMutableArray<ASIndexedNodeContext *> *contexts = [NSMutableArray array];
[indexSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
NSUInteger rowNum = [_dataSource dataController:self rowsInSection:idx];
NSIndexPath *sectionIndex = [[NSIndexPath alloc] initWithIndex:idx];
@ -511,31 +507,9 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
constrainedSize:constrainedSize]];
}
}];
return contexts;
}
/**
* Fetches row contexts for all sections from the data source.
*
* @discussion Results are stored in the passed mutable arrays.
*/
- (void)_populateFromEntireDataSourceWithMutableContexts:(NSMutableArray<ASIndexedNodeContext *> *)contexts
{
NSUInteger sectionNum = [_dataSource numberOfSectionsInDataController:self];
for (NSUInteger i = 0; i < sectionNum; i++) {
NSIndexPath *sectionIndexPath = [[NSIndexPath alloc] initWithIndex:i];
NSUInteger rowNum = [_dataSource dataController:self rowsInSection:i];
for (NSUInteger j = 0; j < rowNum; j++) {
NSIndexPath *indexPath = [sectionIndexPath indexPathByAddingIndex:j];
ASCellNodeBlock nodeBlock = [_dataSource dataController:self nodeBlockAtIndexPath:indexPath];
ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:ASDataControllerRowNodeKind atIndexPath:indexPath];
[contexts addObject:[[ASIndexedNodeContext alloc] initWithNodeBlock:nodeBlock
indexPath:indexPath
constrainedSize:constrainedSize]];
}
}
}
#pragma mark - Batching (External API)
- (void)beginUpdates
@ -617,8 +591,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
[_editingTransactionQueue waitUntilAllOperationsAreFinished];
[self accessDataSourceWithBlock:^{
NSMutableArray<ASIndexedNodeContext *> *contexts = [NSMutableArray array];
[self _populateFromDataSourceWithSectionIndexSet:sections mutableContexts:contexts];
NSArray<ASIndexedNodeContext *> *contexts = [self _populateFromDataSourceWithSectionIndexSet:sections];
[self prepareForInsertSections:sections];
@ -668,8 +641,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
[_editingTransactionQueue waitUntilAllOperationsAreFinished];
[self accessDataSourceWithBlock:^{
NSMutableArray<ASIndexedNodeContext *> *contexts = [NSMutableArray array];
[self _populateFromDataSourceWithSectionIndexSet:sections mutableContexts:contexts];
NSArray<ASIndexedNodeContext *> *contexts= [self _populateFromDataSourceWithSectionIndexSet:sections];
[self prepareForReloadSections:sections];

View File

@ -7,11 +7,9 @@
//
#import <AsyncDisplayKit/ASDataController.h>
#import <AsyncDisplayKit/ASDimension.h>
@interface ASIndexedNodeContext : NSObject
@property (nonatomic, readonly, strong) ASCellNodeBlock nodeBlock;
@property (nonatomic, readonly, strong) NSIndexPath *indexPath;
@property (nonatomic, readonly, assign) ASSizeRange constrainedSize;
@ -19,4 +17,9 @@
indexPath:(NSIndexPath *)indexPath
constrainedSize:(ASSizeRange)constrainedSize;
/**
* Returns a node allocated by executing node block. Node block will be nil out immediately.
*/
- (ASCellNode *)allocateNode;
@end

View File

@ -8,12 +8,20 @@
#import "ASIndexedNodeContext.h"
@interface ASIndexedNodeContext ()
/// Required node block used to allocate a cell node. Nil after the first execution.
@property (nonatomic, strong) ASCellNodeBlock nodeBlock;
@end
@implementation ASIndexedNodeContext
- (instancetype)initWithNodeBlock:(ASCellNodeBlock)nodeBlock
indexPath:(NSIndexPath *)indexPath
constrainedSize:(ASSizeRange)constrainedSize;
{
NSAssert(nodeBlock != nil && indexPath != nil, @"Node block and index path must not be nil");
self = [super init];
if (self) {
_nodeBlock = nodeBlock;
@ -23,4 +31,12 @@
return self;
}
- (ASCellNode *)allocateNode
{
NSAssert(_nodeBlock != nil, @"Node block is gone. Should not execute it more than once");
ASCellNode *node = _nodeBlock();
_nodeBlock = nil;
return node;
}
@end