Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit 58a55f0

Browse files
committed
Merge pull request #529 from facebook/DataControllerQueues
Overhaul ASDataController and extensively test ASTableView.
2 parents 5129708 + 6220d65 commit 58a55f0

File tree

14 files changed

+683
-558
lines changed

14 files changed

+683
-558
lines changed

AsyncDisplayKit/ASDisplayNode.mm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,7 @@ - (void)clearContents
13371337
{
13381338
self.layer.contents = nil;
13391339
_placeholderLayer.contents = nil;
1340+
_placeholderImage = nil;
13401341
}
13411342

13421343
- (void)recursivelyClearContents

AsyncDisplayKit/ASTableView.mm

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#import "ASAssert.h"
1212
#import "ASDataController.h"
13-
#import "ASFlowLayoutController.h"
13+
#import "ASCollectionViewLayoutController.h"
1414
#import "ASLayoutController.h"
1515
#import "ASRangeController.h"
1616
#import "ASDisplayNodeInternal.h"
@@ -160,14 +160,16 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
160160
- (void)configureWithAsyncDataFetching:(BOOL)asyncDataFetchingEnabled
161161
{
162162
_layoutController = [[ASFlowLayoutController alloc] initWithScrollOption:ASFlowLayoutDirectionVertical];
163-
163+
164164
_rangeController = [[ASRangeController alloc] init];
165165
_rangeController.layoutController = _layoutController;
166166
_rangeController.delegate = self;
167167

168168
_dataController = [[ASDataController alloc] initWithAsyncDataFetching:asyncDataFetchingEnabled];
169169
_dataController.dataSource = self;
170170
_dataController.delegate = _rangeController;
171+
172+
_layoutController.dataSource = _dataController;
171173

172174
_asyncDataFetchingEnabled = asyncDataFetchingEnabled;
173175
_asyncDataSourceLocked = NO;
@@ -417,20 +419,12 @@ - (ASScrollDirection)scrollDirection
417419
{
418420
CGPoint scrollVelocity = [self.panGestureRecognizer velocityInView:self.superview];
419421
ASScrollDirection direction = ASScrollDirectionNone;
420-
if (_layoutController.layoutDirection == ASFlowLayoutDirectionHorizontal) {
421-
if (scrollVelocity.x > 0) {
422-
direction = ASScrollDirectionRight;
423-
} else if (scrollVelocity.x < 0) {
424-
direction = ASScrollDirectionLeft;
425-
}
422+
if (scrollVelocity.y > 0) {
423+
direction = ASScrollDirectionDown;
426424
} else {
427-
if (scrollVelocity.y > 0) {
428-
direction = ASScrollDirectionDown;
429-
} else {
430-
direction = ASScrollDirectionUp;
431-
}
425+
direction = ASScrollDirectionUp;
432426
}
433-
427+
434428
return direction;
435429
}
436430

AsyncDisplayKit/Details/ASCollectionViewLayoutController.mm

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
typedef struct ASDirectionalScreenfulBuffer ASDirectionalScreenfulBuffer;
2222

2323
ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferHorizontal(ASScrollDirection scrollDirection,
24-
ASRangeTuningParameters rangeTuningParameters) {
24+
ASRangeTuningParameters rangeTuningParameters)
25+
{
2526
ASDirectionalScreenfulBuffer horizontalBuffer = {0, 0};
2627
BOOL movingRight = ASScrollDirectionContainsRight(scrollDirection);
2728
horizontalBuffer.positiveDirection = movingRight ? rangeTuningParameters.leadingBufferScreenfuls :
@@ -32,7 +33,8 @@ ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferHorizontal(ASScrollDire
3233
}
3334

3435
ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferVertical(ASScrollDirection scrollDirection,
35-
ASRangeTuningParameters rangeTuningParameters) {
36+
ASRangeTuningParameters rangeTuningParameters)
37+
{
3638
ASDirectionalScreenfulBuffer verticalBuffer = {0, 0};
3739
BOOL movingDown = ASScrollDirectionContainsDown(scrollDirection);
3840
verticalBuffer.positiveDirection = movingDown ? rangeTuningParameters.leadingBufferScreenfuls :
@@ -52,19 +54,26 @@ ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferVertical(ASScrollDirect
5254
#pragma mark -
5355
#pragma mark ASCollectionViewLayoutController
5456

55-
@interface ASCollectionViewLayoutController () {
56-
ASCollectionView * __weak _collectionView;
57+
@interface ASCollectionViewLayoutController ()
58+
{
59+
UIScrollView * __weak _scrollView;
60+
UICollectionViewLayout * __strong _collectionViewLayout;
5761
std::vector<CGRect> _updateRangeBoundsIndexedByRangeType;
62+
ASScrollDirection _scrollableDirections;
5863
}
5964
@end
6065

6166
@implementation ASCollectionViewLayoutController
6267

63-
- (instancetype)initWithCollectionView:(ASCollectionView *)collectionView {
68+
- (instancetype)initWithCollectionView:(ASCollectionView *)collectionView
69+
{
6470
if (!(self = [super init])) {
6571
return nil;
6672
}
67-
_collectionView = collectionView;
73+
74+
_scrollableDirections = [collectionView scrollableDirections];
75+
_scrollView = collectionView;
76+
_collectionViewLayout = [collectionView collectionViewLayout];
6877
_updateRangeBoundsIndexedByRangeType = std::vector<CGRect>(ASLayoutRangeTypeCount);
6978
return self;
7079
}
@@ -74,22 +83,21 @@ - (instancetype)initWithCollectionView:(ASCollectionView *)collectionView {
7483

7584
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection
7685
viewportSize:(CGSize)viewportSize
77-
rangeType:(ASLayoutRangeType)rangeType {
86+
rangeType:(ASLayoutRangeType)rangeType
87+
{
7888
ASRangeGeometry rangeGeometry = [self rangeGeometryWithScrollDirection:scrollDirection
79-
collectionView:_collectionView
8089
rangeTuningParameters:[self tuningParametersForRangeType:rangeType]];
8190
_updateRangeBoundsIndexedByRangeType[rangeType] = rangeGeometry.updateBounds;
82-
return [self indexPathsForItemsWithinRangeBounds:rangeGeometry.rangeBounds collectionView:_collectionView];
91+
return [self indexPathsForItemsWithinRangeBounds:rangeGeometry.rangeBounds];
8392
}
8493

8594
- (ASRangeGeometry)rangeGeometryWithScrollDirection:(ASScrollDirection)scrollDirection
86-
collectionView:(ASCollectionView *)collectionView
87-
rangeTuningParameters:(ASRangeTuningParameters)rangeTuningParameters {
88-
CGRect rangeBounds = collectionView.bounds;
89-
CGRect updateBounds = collectionView.bounds;
90-
ASScrollDirection scrollableDirections = [collectionView scrollableDirections];
95+
rangeTuningParameters:(ASRangeTuningParameters)rangeTuningParameters
96+
{
97+
CGRect rangeBounds = _scrollView.bounds;
98+
CGRect updateBounds = _scrollView.bounds;
9199

92-
BOOL canScrollHorizontally = ASScrollDirectionContainsHorizontalDirection(scrollableDirections);
100+
BOOL canScrollHorizontally = ASScrollDirectionContainsHorizontalDirection(_scrollableDirections);
93101
if (canScrollHorizontally) {
94102
ASDirectionalScreenfulBuffer horizontalBuffer = ASDirectionalScreenfulBufferHorizontal(scrollDirection,
95103
rangeTuningParameters);
@@ -102,7 +110,7 @@ - (ASRangeGeometry)rangeGeometryWithScrollDirection:(ASScrollDirection)scrollDir
102110
MIN(horizontalBuffer.positiveDirection * 0.5, 0.95));
103111
}
104112

105-
BOOL canScrollVertically = ASScrollDirectionContainsVerticalDirection(scrollableDirections);
113+
BOOL canScrollVertically = ASScrollDirectionContainsVerticalDirection(_scrollableDirections);
106114
if (canScrollVertically) {
107115
ASDirectionalScreenfulBuffer verticalBuffer = ASDirectionalScreenfulBufferVertical(scrollDirection,
108116
rangeTuningParameters);
@@ -118,9 +126,10 @@ - (ASRangeGeometry)rangeGeometryWithScrollDirection:(ASScrollDirection)scrollDir
118126
return {rangeBounds, updateBounds};
119127
}
120128

121-
- (NSSet *)indexPathsForItemsWithinRangeBounds:(CGRect)rangeBounds collectionView:(ASCollectionView *)collectionView {
129+
- (NSSet *)indexPathsForItemsWithinRangeBounds:(CGRect)rangeBounds
130+
{
122131
NSMutableSet *indexPathSet = [[NSMutableSet alloc] init];
123-
NSArray *layoutAttributes = [collectionView.collectionViewLayout layoutAttributesForElementsInRect:rangeBounds];
132+
NSArray *layoutAttributes = [_collectionViewLayout layoutAttributesForElementsInRect:rangeBounds];
124133
for (UICollectionViewLayoutAttributes *la in layoutAttributes) {
125134
[indexPathSet addObject:la.indexPath];
126135
}
@@ -132,13 +141,14 @@ - (NSSet *)indexPathsForItemsWithinRangeBounds:(CGRect)rangeBounds collectionVie
132141

133142
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray *)indexPaths
134143
viewportSize:(CGSize)viewportSize
135-
rangeType:(ASLayoutRangeType)rangeType {
144+
rangeType:(ASLayoutRangeType)rangeType
145+
{
136146
CGRect updateRangeBounds = _updateRangeBoundsIndexedByRangeType[rangeType];
137147
if (CGRectIsEmpty(updateRangeBounds)) {
138148
return YES;
139149
}
140150

141-
CGRect currentBounds = _collectionView.bounds;
151+
CGRect currentBounds = _scrollView.bounds;
142152
if (CGRectIsEmpty(currentBounds)) {
143153
currentBounds = CGRectMake(0, 0, viewportSize.width, viewportSize.height);
144154
}

AsyncDisplayKit/Details/ASDataController.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#import <UIKit/UIKit.h>
1010
#import <AsyncDisplayKit/ASDealloc2MainObject.h>
11-
11+
#import "ASFlowLayoutController.h"
1212

1313
@class ASCellNode;
1414
@class ASDataController;
@@ -70,25 +70,21 @@ typedef NSUInteger ASDataControllerAnimationOptions;
7070
/**
7171
Called for insertion of elements.
7272
*/
73-
- (void)dataController:(ASDataController *)dataController willInsertNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions;
7473
- (void)dataController:(ASDataController *)dataController didInsertNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions;
7574

7675
/**
7776
Called for deletion of elements.
7877
*/
79-
- (void)dataController:(ASDataController *)dataController willDeleteNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions;
8078
- (void)dataController:(ASDataController *)dataController didDeleteNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions;
8179

8280
/**
8381
Called for insertion of sections.
8482
*/
85-
- (void)dataController:(ASDataController *)dataController willInsertSections:(NSArray *)sections atIndexSet:(NSIndexSet *)indexSet withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions;
8683
- (void)dataController:(ASDataController *)dataController didInsertSections:(NSArray *)sections atIndexSet:(NSIndexSet *)indexSet withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions;
8784

8885
/**
8986
Called for deletion of sections.
9087
*/
91-
- (void)dataController:(ASDataController *)dataController willDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions;
9288
- (void)dataController:(ASDataController *)dataController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions;
9389

9490
@end
@@ -101,7 +97,8 @@ typedef NSUInteger ASDataControllerAnimationOptions;
10197
* will be updated asynchronously. The dataSource must be updated to reflect the changes before these methods has been called.
10298
* For each data updatin, the corresponding methods in delegate will be called.
10399
*/
104-
@interface ASDataController : ASDealloc2MainObject
100+
@protocol ASFlowLayoutControllerDataSource;
101+
@interface ASDataController : ASDealloc2MainObject <ASFlowLayoutControllerDataSource>
105102

106103
/**
107104
Data source for fetching data info.
@@ -117,7 +114,7 @@ typedef NSUInteger ASDataControllerAnimationOptions;
117114
* Designated iniailizer.
118115
*
119116
* @param asyncDataFetchingEnabled Enable the data fetching in async mode.
120-
117+
*
121118
* @discussion If enabled, we will fetch data through `dataController:nodeAtIndexPath:` and `dataController:rowsInSection:` in background thread.
122119
* Otherwise, the methods will be invoked synchronically in calling thread. Enabling data fetching in async mode could avoid blocking main thread
123120
* while allocating cell on main thread, which is frequently reported issue for handling large scale data. On another hand, the application code
@@ -127,7 +124,11 @@ typedef NSUInteger ASDataControllerAnimationOptions;
127124
*/
128125
- (instancetype)initWithAsyncDataFetching:(BOOL)asyncDataFetchingEnabled;
129126

130-
/** @name Initial loading */
127+
/** @name Initial loading
128+
*
129+
* @discussion This method allows choosing an animation style for the first load of content. It is typically used just once,
130+
* for example in viewWillAppear:, to specify an animation option for the information already present in the asyncDataSource.
131+
*/
131132

132133
- (void)initialDataLoadingWithAnimationOptions:(ASDataControllerAnimationOptions)animationOptions;
133134

@@ -167,4 +168,6 @@ typedef NSUInteger ASDataControllerAnimationOptions;
167168

168169
- (NSArray *)nodesAtIndexPaths:(NSArray *)indexPaths;
169170

171+
- (NSArray *)completedNodes; // This provides efficient access to the entire _completedNodes multidimensional array.
172+
170173
@end

0 commit comments

Comments
 (0)