diff --git a/AsyncDisplayKit/ASCollectionView.h b/AsyncDisplayKit/ASCollectionView.h index d3d08048e6..17fef509f4 100644 --- a/AsyncDisplayKit/ASCollectionView.h +++ b/AsyncDisplayKit/ASCollectionView.h @@ -131,7 +131,13 @@ */ - (void)reloadData; -- (void)reloadDataAndWait; +/** + * Reload everything from scratch entirely on the main thread, destroying the working range and all cached nodes. + * + * @warning This method is substantially more expensive than UICollectionView's version and will block the main thread + * while all the cells load. + */ +- (void)reloadDataImmediately; /** * Registers the given kind of supplementary node for use in creating node-backed supplementary views. diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index e1535f4c2a..8ff35ef62d 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -280,9 +280,10 @@ static BOOL _isInterceptedSelector(SEL sel) [self reloadDataWithCompletion:nil]; } -- (void)reloadDataAndWait +- (void)reloadDataImmediatelyWithAnimationOptions:(ASDataControllerAnimationOptions)animationOptions { - [_dataController reloadDataAndWait]; + ASDisplayNodeAssertMainThread(); + [_dataController reloadDataImmediatelyWithAnimationOptions:animationOptions]; [super reloadData]; } diff --git a/AsyncDisplayKit/ASTableView.h b/AsyncDisplayKit/ASTableView.h index b7588f782b..d7ea79dc2d 100644 --- a/AsyncDisplayKit/ASTableView.h +++ b/AsyncDisplayKit/ASTableView.h @@ -93,6 +93,14 @@ */ - (void)reloadData; +/** + * Reload everything from scratch entirely on the main thread, destroying the working range and all cached nodes. + * + * @warning This method is substantially more expensive than UITableView's version and will block the main thread while + * all the cells load. + */ +- (void)reloadDataImmediately; + /** * begins a batch of insert, delete reload and move operations. This method must be called from the main thread. */ diff --git a/AsyncDisplayKit/ASTableView.mm b/AsyncDisplayKit/ASTableView.mm index 314d7664c6..30f19e48cc 100644 --- a/AsyncDisplayKit/ASTableView.mm +++ b/AsyncDisplayKit/ASTableView.mm @@ -334,6 +334,13 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) { [self reloadDataWithCompletion:nil]; } +- (void)reloadDataImmediately +{ + ASDisplayNodeAssertMainThread(); + [_dataController reloadDataImmediatelyWithAnimationOptions:UITableViewRowAnimationNone]; + [super reloadData]; +} + - (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType { [_layoutController setTuningParameters:tuningParameters forRangeType:rangeType]; diff --git a/AsyncDisplayKit/Details/ASDataController.h b/AsyncDisplayKit/Details/ASDataController.h index 0112a298ec..1dde3647b5 100644 --- a/AsyncDisplayKit/Details/ASDataController.h +++ b/AsyncDisplayKit/Details/ASDataController.h @@ -168,7 +168,7 @@ typedef NSUInteger ASDataControllerAnimationOptions; - (void)reloadDataWithAnimationOptions:(ASDataControllerAnimationOptions)animationOptions completion:(void (^)())completion; -- (void)reloadDataAndWait; +- (void)reloadDataImmediatelyWithAnimationOptions:(ASDataControllerAnimationOptions)animationOptions; /** @name Data Querying */ diff --git a/AsyncDisplayKit/Details/ASDataController.mm b/AsyncDisplayKit/Details/ASDataController.mm index 6314411dd2..79436b3316 100644 --- a/AsyncDisplayKit/Details/ASDataController.mm +++ b/AsyncDisplayKit/Details/ASDataController.mm @@ -151,8 +151,6 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; - (void)_layoutNodes:(NSArray *)nodes ofKind:(NSString *)kind atIndexPaths:(NSArray *)indexPaths completion:(void (^)(NSArray *nodes, NSArray *indexPaths))completionBlock { - ASDisplayNodeAssert([NSOperationQueue currentQueue] == _editingTransactionQueue, @"Cell node layout must be initiated from edit transaction queue"); - if (!nodes.count) { return; } @@ -356,12 +354,22 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; } - (void)reloadDataWithAnimationOptions:(ASDataControllerAnimationOptions)animationOptions completion:(void (^)())completion +{ + [self _reloadDataWithAnimationOptions:animationOptions synchronously:NO completion:completion]; +} + +- (void)reloadDataImmediatelyWithAnimationOptions:(ASDataControllerAnimationOptions)animationOptions +{ + [self _reloadDataWithAnimationOptions:animationOptions synchronously:YES completion:nil]; +} + +- (void)_reloadDataWithAnimationOptions:(ASDataControllerAnimationOptions)animationOptions synchronously:(BOOL)synchronously completion:(void (^)())completion { [self performEditCommandWithBlock:^{ ASDisplayNodeAssertMainThread(); [_editingTransactionQueue waitUntilAllOperationsAreFinished]; - [self accessDataSourceWithBlock:^{ + [self accessDataSourceSynchronously:synchronously withBlock:^{ NSUInteger sectionCount = [_dataSource numberOfSectionsInDataController:self]; NSMutableArray *updatedNodes = [NSMutableArray array]; NSMutableArray *updatedIndexPaths = [NSMutableArray array]; @@ -373,7 +381,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; // Allow subclasses to perform setup before going into the edit transaction [self prepareForReloadData]; - [_editingTransactionQueue addOperationWithBlock:^{ + void (^transactionBlock)() = ^{ LOG(@"Edit Transaction - reloadData"); // Remove everything that existed before the reload, now that we're ready to insert replacements @@ -399,52 +407,13 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; if (completion) { dispatch_async(dispatch_get_main_queue(), completion); } - }]; - }]; - }]; -} - -- (void)reloadDataAndWait -{ - [self performEditCommandWithBlock:^{ - ASDisplayNodeAssertMainThread(); - [_editingTransactionQueue waitUntilAllOperationsAreFinished]; - - [self accessDataSourceSynchronously:YES withBlock:^{ - NSUInteger sectionCount = [_dataSource numberOfSectionsInDataController:self]; - NSMutableArray *updatedNodes = [NSMutableArray array]; - NSMutableArray *updatedIndexPaths = [NSMutableArray array]; - [self _populateFromEntireDataSourceWithMutableNodes:updatedNodes mutableIndexPaths:updatedIndexPaths]; + }; - // Measure nodes whose views are loaded before we leave the main thread - [self layoutLoadedNodes:updatedNodes ofKind:ASDataControllerRowNodeKind atIndexPaths:updatedIndexPaths]; - - // Allow subclasses to perform setup before going into the edit transaction - [self prepareForReloadData]; - - LOG(@"Edit Transaction - reloadData"); - - ASDataControllerAnimationOptions animationOptions = UITableViewRowAnimationNone; - - // Remove everything that existed before the reload, now that we're ready to insert replacements - NSArray *indexPaths = ASIndexPathsForMultidimensionalArray(_editingNodes[ASDataControllerRowNodeKind]); - [self _deleteNodesAtIndexPaths:indexPaths withAnimationOptions:animationOptions]; - - NSMutableArray *editingNodes = _editingNodes[ASDataControllerRowNodeKind]; - NSMutableIndexSet *indexSet = [[NSMutableIndexSet alloc] initWithIndexesInRange:NSMakeRange(0, editingNodes.count)]; - [self _deleteSectionsAtIndexSet:indexSet withAnimationOptions:animationOptions]; - - [self willReloadData]; - - // Insert each section - NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount]; - for (int i = 0; i < sectionCount; i++) { - [sections addObject:[[NSMutableArray alloc] init]]; + if (synchronously) { + transactionBlock(); + } else { + [_editingTransactionQueue addOperationWithBlock:transactionBlock]; } - - [self _insertSections:sections atIndexSet:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, sectionCount)] withAnimationOptions:animationOptions]; - - [self _batchLayoutNodes:updatedNodes atIndexPaths:updatedIndexPaths withAnimationOptions:animationOptions]; }]; }]; } diff --git a/examples/SynchronousKittens/Sample.xcodeproj/project.pbxproj b/examples/SynchronousKittens/Sample.xcodeproj/project.pbxproj index ddfd884074..a8ef05da55 100644 --- a/examples/SynchronousKittens/Sample.xcodeproj/project.pbxproj +++ b/examples/SynchronousKittens/Sample.xcodeproj/project.pbxproj @@ -128,6 +128,7 @@ 05E2127E19D4DB510098F589 /* Frameworks */, 05E2127F19D4DB510098F589 /* Resources */, F012A6F39E0149F18F564F50 /* Copy Pods Resources */, + ACCB3408566E7626721EF2D5 /* Embed Pods Frameworks */, ); buildRules = ( ); @@ -184,6 +185,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + ACCB3408566E7626721EF2D5 /* Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; E080B80F89C34A25B3488E26 /* Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/examples/SynchronousKittens/Sample/ViewController.m b/examples/SynchronousKittens/Sample/ViewController.m index 7989fe15ce..5d0b594879 100644 --- a/examples/SynchronousKittens/Sample/ViewController.m +++ b/examples/SynchronousKittens/Sample/ViewController.m @@ -94,6 +94,8 @@ static const NSInteger kMaxLitterSize = 100; // max number of kitten cell [super viewDidLoad]; [self.view addSubview:_tableView]; + + [_tableView reloadDataImmediately]; } - (void)viewWillLayoutSubviews