Peter 9bc996374f Add 'submodules/AsyncDisplayKit/' from commit '02bedc12816e251ad71777f9d2578329b6d2bef6'
git-subtree-dir: submodules/AsyncDisplayKit
git-subtree-mainline: d06f423e0ed3df1fed9bd10d79ee312a9179b632
git-subtree-split: 02bedc12816e251ad71777f9d2578329b6d2bef6
2019-06-11 18:42:43 +01:00

4.3 KiB
Executable File
Raw Blame History

title layout permalink
Prefer `nodeBlocks` for Performance docs /docs/tip-1-nodeBlocks.html

Textures ASCollectionNode replaces UICollectionViews required method

Swift Objective-C
collectionView:cellForItemAtIndexPath:
  
  

with your choice of **one** of the two following methods
Swift Objective-C
// called on main thread, ASCellNode initialized on main and then returned 
collectionNode:nodeForItemAtIndexPath: 

OR

// called on main thread, ASCellNodeBlock returned, then // ASCellNode initialized in background when block is called by system collectionNode:nodeBlockForItemAtIndexPath:

  

`ASTableNode` has the same options:
Swift Objective-C
`tableNode:nodeForRow:`
`tableNode:nodeBlockforRow:`    // preferred
  
  

ASPagerNode does as well:

Swift Objective-C
`pagerNode:nodeAtIndex:`
`pagerNode:nodeBlockAtIndex:`   // preferred
  
  

We recommend that you use nodeBlocks. Using the nodeBlock method allows table and collections to request blocks for each cell node, and execute them concurrently across multiple threads, which allows us to parallelize the allocation costs (in addition to layout measurement).

This leaves our main thread more free to handle touch events and other time sensitive work, keeping our user's taps happy and responsive.

Access your data source outside of the nodeBlock

Because nodeBlocks are executed on a background thread, it is very important they be thread-safe.

The most important aspect to consider is accessing properties on self that may change, such as an array of data models. This can be handled safely by ensuring that any immutable state is collected above the node block.

Using the indexPath parameter to access a mutable collection inside the node block is not safe. This is because by the time the block runs, the dataSource may have changed.

Here's an example of a simple nodeBlock:

Swift Objective-C
- (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath
{
    // data model is accessed outside of the node block
    Board *board = [self.boards objectAtIndex:indexPath.item];
    return ^{
        BoardScrubberCellNode *node = [[BoardScrubberCellNode alloc] initWithBoard:board];
        return node;
    };
}
  
  

Note that it is okay to use the indexPath if it is used strictly for its integer values and not to index a value from a mutable data source.

Do not return nil from a nodeBlock

Just as when UIKit requests a cell, returning nil will crash the app, so it is important to ensure a valid ASCellNode is returned for either the node or nodeBlock method. Your code should ensure that at least a blank ASCellNode is returned, but ideally the number of items reported to the collection would prevent the method from being called when there is no data to display.