From 3e5daf4ccde39fdc6951805029ea1ecbadc3b2cf Mon Sep 17 00:00:00 2001 From: Rahul Malik Date: Tue, 9 Feb 2016 22:47:43 -0800 Subject: [PATCH] Update data source protocols to make synchronous node creation api methods optional. --- AsyncDisplayKit/ASCollectionView.h | 9 +++-- AsyncDisplayKit/ASCollectionView.mm | 17 ++------ AsyncDisplayKit/ASPagerNode.h | 39 ++++++++++++++++--- AsyncDisplayKit/ASPagerNode.m | 10 ++--- AsyncDisplayKit/ASTableView.h | 7 ++-- AsyncDisplayKit/ASTableView.mm | 17 +++----- .../Details/ASCollectionDataController.h | 4 +- .../Details/ASCollectionDataController.mm | 2 + AsyncDisplayKit/Details/ASDataController.h | 5 --- 9 files changed, 58 insertions(+), 52 deletions(-) diff --git a/AsyncDisplayKit/ASCollectionView.h b/AsyncDisplayKit/ASCollectionView.h index 3e01e095..6b4f8a38 100644 --- a/AsyncDisplayKit/ASCollectionView.h +++ b/AsyncDisplayKit/ASCollectionView.h @@ -340,6 +340,8 @@ NS_ASSUME_NONNULL_BEGIN #define ASCollectionViewDataSource ASCollectionDataSource @protocol ASCollectionDataSource +@optional + /** * Similar to -collectionView:cellForItemAtIndexPath:. * @@ -353,16 +355,15 @@ NS_ASSUME_NONNULL_BEGIN */ - (ASCellNode *)collectionView:(ASCollectionView *)collectionView nodeForItemAtIndexPath:(NSIndexPath *)indexPath; - -@optional - /** + * Similar to -collectionView:nodeForItemAtIndexPath: + * This method takes precedence over collectionView:nodeForItemAtIndexPath: if implemented. * * @param collectionView The sender. * * @param indexPath The index path of the requested node. * - * @returns a block that creates the node for display at this indexpath. + * @returns a block that creates the node for display at this indexpath. * Must be thread-safe (can be called on the main thread or a background * queue) and should not implement reuse (it will be called once per row). */ diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index 23ae37ae..eda88bf7 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -294,7 +294,6 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; // super.dataSource in this case because calls to ASCollectionViewProxy will start failing and cause crashes. super.dataSource = nil; - if (asyncDataSource == nil) { _asyncDataSource = nil; _proxyDataSource = _isDeallocating ? nil : [[ASCollectionViewProxy alloc] initWithTarget:nil interceptor:self]; @@ -305,6 +304,9 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; _proxyDataSource = [[ASCollectionViewProxy alloc] initWithTarget:_asyncDataSource interceptor:self]; _asyncDataSourceImplementsConstrainedSizeForNode = [_asyncDataSource respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)]; _asyncDataSourceImplementsNodeBlockForItemAtIndexPath = [_asyncDataSource respondsToSelector:@selector(collectionView:nodeBlockForItemAtIndexPath:)]; + + // Data-source must implement collectionView:nodeForItemAtIndexPath: or collectionView:nodeBlockForItemAtIndexPath: + ASDisplayNodeAssertTrue(_asyncDataSourceImplementsNodeBlockForItemAtIndexPath || [_asyncDataSource respondsToSelector:@selector(collectionView:nodeForItemAtIndexPath:)]); } super.dataSource = (id)_proxyDataSource; @@ -678,19 +680,6 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; #pragma mark - ASDataControllerSource -- (ASCellNode *)dataController:(ASDataController *)dataController nodeAtIndexPath:(NSIndexPath *)indexPath -{ - ASCellNode *node = [_asyncDataSource collectionView:self nodeForItemAtIndexPath:indexPath]; - [node enterHierarchyState:ASHierarchyStateRangeManaged]; - - ASDisplayNodeAssert([node isKindOfClass:ASCellNode.class], @"invalid node class, expected ASCellNode"); - if (node.layoutDelegate == nil) { - node.layoutDelegate = self; - } - return node; -} - - - (ASCellNodeBlock)dataController:(ASDataController *)dataController nodeBlockAtIndexPath:(NSIndexPath *)indexPath { if (!_asyncDataSourceImplementsNodeBlockForItemAtIndexPath) { diff --git a/AsyncDisplayKit/ASPagerNode.h b/AsyncDisplayKit/ASPagerNode.h index 1b36e45b..3596dfca 100644 --- a/AsyncDisplayKit/ASPagerNode.h +++ b/AsyncDisplayKit/ASPagerNode.h @@ -10,15 +10,44 @@ @class ASPagerNode; @protocol ASPagerNodeDataSource -// This method replaces -collectionView:numberOfItemsInSection: -- (NSInteger)numberOfPagesInPagerNode:(ASPagerNode *)pagerNode; -// This method replaces -collectionView:nodeForItemAtIndexPath: -- (ASCellNode *)pagerNode:(ASPagerNode *)pagerNode nodeAtIndex:(NSInteger)index; +/** + * This method replaces -collectionView:numberOfItemsInSection: + * + * @param pagerNode The sender. + * + * + * @returns The total number of pages that can display in the pagerNode. + */ +- (NSInteger)numberOfPagesInPagerNode:(ASPagerNode *)pagerNode; @optional -// This method replaces -collectionView:nodeBlockForItemAtIndexPath: +/** + * This method replaces -collectionView:nodeForItemAtIndexPath: + * + * @param pagerNode The sender. + * + * @param index The index of the requested node. + * + * @returns a node for display at this index. This will be called on the main thread and should + * not implement reuse (it will be called once per row). Unlike UICollectionView's version, + * this method is not called when the row is about to display. + */ +- (ASCellNode *)pagerNode:(ASPagerNode *)pagerNode nodeAtIndex:(NSInteger)index; + +/** + * This method replaces -collectionView:nodeBlockForItemAtIndexPath: + * This method takes precedence over pagerNode:nodeAtIndex: if implemented. + * + * @param pagerNode The sender. + * + * @param index The index of the requested node. + * + * @returns a block that creates the node for display at this index. + * Must be thread-safe (can be called on the main thread or a background + * queue) and should not implement reuse (it will be called once per row). + */ - (ASCellNodeBlock)pagerNode:(ASPagerNode *)pagerNode nodeBlockAtIndex:(NSInteger)index; @end diff --git a/AsyncDisplayKit/ASPagerNode.m b/AsyncDisplayKit/ASPagerNode.m index bcd275cb..4d7ee51f 100644 --- a/AsyncDisplayKit/ASPagerNode.m +++ b/AsyncDisplayKit/ASPagerNode.m @@ -83,13 +83,6 @@ #pragma mark - ASCollectionViewDataSource -- (ASCellNode *)collectionView:(ASCollectionView *)collectionView nodeForItemAtIndexPath:(NSIndexPath *)indexPath -{ - ASDisplayNodeAssert(_pagerDataSource != nil, @"ASPagerNode must have a data source to load nodes to display"); - ASCellNode *pageNode = [_pagerDataSource pagerNode:self nodeAtIndex:indexPath.item]; - return pageNode; -} - - (ASCellNodeBlock)collectionView:(ASCollectionView *)collectionView nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath { ASDisplayNodeAssert(_pagerDataSource != nil, @"ASPagerNode must have a data source to load nodes to display"); @@ -123,7 +116,10 @@ if (pagerDataSource != _pagerDataSource) { _pagerDataSource = pagerDataSource; _pagerDataSourceImplementsNodeBlockAtIndex = [_pagerDataSource respondsToSelector:@selector(pagerNode:nodeBlockAtIndex:)]; + // Data source must implement pagerNode:nodeBlockAtIndex: or pagerNode:nodeAtIndex: + ASDisplayNodeAssertTrue(_pagerDataSourceImplementsNodeBlockAtIndex || [_pagerDataSource respondsToSelector:@selector(pagerNode:nodeAtIndex:)]); _proxy = pagerDataSource ? [[ASPagerNodeProxy alloc] initWithTarget:pagerDataSource interceptor:self] : nil; + super.dataSource = (id )_proxy; } } diff --git a/AsyncDisplayKit/ASTableView.h b/AsyncDisplayKit/ASTableView.h index f7a51fc7..b21d2ac9 100644 --- a/AsyncDisplayKit/ASTableView.h +++ b/AsyncDisplayKit/ASTableView.h @@ -315,6 +315,8 @@ NS_ASSUME_NONNULL_BEGIN */ @protocol ASTableDataSource +@optional + /** * Similar to -tableView:cellForRowAtIndexPath:. * @@ -327,11 +329,10 @@ NS_ASSUME_NONNULL_BEGIN */ - (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSIndexPath *)indexPath; -@optional /** - * Similar to -tableView:nodeForRowAtIndexPath:. - * + * Similar to -tableView:nodeForRowAtIndexPath: + * This method takes precedence over tableView:nodeForRowAtIndexPath: if implemented. * @param tableView The sender. * * @param indexPath The index path of the requested node. diff --git a/AsyncDisplayKit/ASTableView.mm b/AsyncDisplayKit/ASTableView.mm index 28d8ef3d..111e5afe 100644 --- a/AsyncDisplayKit/ASTableView.mm +++ b/AsyncDisplayKit/ASTableView.mm @@ -111,6 +111,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; BOOL _ignoreNodesConstrainedWidthChange; BOOL _queuedNodeHeightUpdate; BOOL _isDeallocating; + BOOL _dataSourceImplementsNodeBlockForRowAtIndexPath; } @property (atomic, assign) BOOL asyncDataSourceLocked; @@ -256,8 +257,12 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; if (asyncDataSource == nil) { _asyncDataSource = nil; _proxyDataSource = _isDeallocating ? nil : [[ASTableViewProxy alloc] initWithTarget:nil interceptor:self]; + _dataSourceImplementsNodeBlockForRowAtIndexPath = NO; } else { _asyncDataSource = asyncDataSource; + _dataSourceImplementsNodeBlockForRowAtIndexPath = [_asyncDataSource respondsToSelector:@selector(tableView:nodeBlockForRowAtIndexPath:)]; + // Data source must implement tableView:nodeBlockForRowAtIndexPath: or tableView:nodeForRowAtIndexPath: + ASDisplayNodeAssertTrue(_dataSourceImplementsNodeBlockForRowAtIndexPath || [_asyncDataSource respondsToSelector:@selector(tableView:nodeForRowAtIndexPath:)]); _proxyDataSource = [[ASTableViewProxy alloc] initWithTarget:_asyncDataSource interceptor:self]; } @@ -862,18 +867,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; #pragma mark - ASDataControllerDelegate -- (ASCellNode *)dataController:(ASDataController *)dataController nodeAtIndexPath:(NSIndexPath *)indexPath -{ - ASCellNode *node = [_asyncDataSource tableView:self nodeForRowAtIndexPath:indexPath]; - [node enterHierarchyState:ASHierarchyStateRangeManaged]; - - ASDisplayNodeAssert([node isKindOfClass:ASCellNode.class], @"invalid node class, expected ASCellNode"); - if (node.layoutDelegate == nil) { - node.layoutDelegate = self; - } - return node; -} - - (ASCellNodeBlock)dataController:(ASDataController *)dataController nodeBlockAtIndexPath:(NSIndexPath *)indexPath { if (![_asyncDataSource respondsToSelector:@selector(tableView:nodeBlockForRowAtIndexPath:)]) { ASCellNode *node = [_asyncDataSource tableView:self nodeForRowAtIndexPath:indexPath]; diff --git a/AsyncDisplayKit/Details/ASCollectionDataController.h b/AsyncDisplayKit/Details/ASCollectionDataController.h index 1ac859cf..ec7a3063 100644 --- a/AsyncDisplayKit/Details/ASCollectionDataController.h +++ b/AsyncDisplayKit/Details/ASCollectionDataController.h @@ -17,8 +17,6 @@ @protocol ASCollectionDataControllerSource -- (ASCellNode *)dataController:(ASCollectionDataController *)dataController supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath; - /** The constrained size range for layout. */ @@ -32,6 +30,8 @@ @optional +- (ASCellNode *)dataController:(ASCollectionDataController *)dataController supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath; + - (ASCellNodeBlock)dataController:(ASCollectionDataController *)dataController supplementaryNodeBlockOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath; @end diff --git a/AsyncDisplayKit/Details/ASCollectionDataController.mm b/AsyncDisplayKit/Details/ASCollectionDataController.mm index 90b1be92..2408a57e 100644 --- a/AsyncDisplayKit/Details/ASCollectionDataController.mm +++ b/AsyncDisplayKit/Details/ASCollectionDataController.mm @@ -255,6 +255,8 @@ { [super setDataSource:dataSource]; _dataSourceImplementsSupplementaryNodeBlockOfKindAtIndexPath = [self.collectionDataSource respondsToSelector:@selector(dataController:supplementaryNodeBlockOfKind:atIndexPath:)]; + + ASDisplayNodeAssertTrue(_dataSourceImplementsSupplementaryNodeBlockOfKindAtIndexPath || [self.collectionDataSource respondsToSelector:@selector(dataController:supplementaryNodeOfKind:atIndexPath:)]); } @end \ No newline at end of file diff --git a/AsyncDisplayKit/Details/ASDataController.h b/AsyncDisplayKit/Details/ASDataController.h index ed1f453a..6648275d 100644 --- a/AsyncDisplayKit/Details/ASDataController.h +++ b/AsyncDisplayKit/Details/ASDataController.h @@ -35,11 +35,6 @@ FOUNDATION_EXPORT NSString * const ASDataControllerRowNodeKind; @protocol ASDataControllerSource -/** - Fetch the ASCellNode for specific index path. - */ -- (ASCellNode *)dataController:(ASDataController *)dataController nodeAtIndexPath:(NSIndexPath *)indexPath; - /** Fetch the ASCellNode block for specific index path. This block should return the ASCellNode for the specified index path. */