From eba6afc36b8183a3e37bd150f01e9597a9402641 Mon Sep 17 00:00:00 2001 From: Garrett Moon Date: Tue, 1 Mar 2016 16:45:36 -0800 Subject: [PATCH 1/2] Revert "Don't clear contents when moving between nodes" This reverts commit 6d1732fcbdda44603577979afdddb9fc48b6d6e4. --- AsyncDisplayKit/ASDisplayNode.mm | 26 +++---------------- .../Private/ASDisplayNodeInternal.h | 1 - 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index 2ba6a00097..af1d9c9d6e 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -1227,7 +1227,7 @@ static bool disableNotificationsForMovingBetweenParents(ASDisplayNode *from, ASD if (isMovingEquivalentParents) { [subnode __incrementVisibilityNotificationsDisabled]; } - [subnode removeFromSupernodeMovingBetweenNodes:YES]; + [subnode removeFromSupernode]; if (!_subnodes) _subnodes = [[NSMutableArray alloc] init]; @@ -1497,11 +1497,6 @@ static NSInteger incrementIfFound(NSInteger i) { } - (void)removeFromSupernode -{ - [self removeFromSupernodeMovingBetweenNodes:NO]; -} - -- (void)removeFromSupernodeMovingBetweenNodes:(BOOL)movingBetweenNodes { ASDisplayNodeAssertThreadAffinity(self); BOOL shouldRemoveFromSuperviewOrSuperlayer = NO; @@ -1510,7 +1505,7 @@ static NSInteger incrementIfFound(NSInteger i) { ASDN::MutexLocker l(_propertyLock); if (!_supernode) return; - + // Check to ensure that our view or layer is actually inside of our supernode; otherwise, don't remove it. // Though _ASDisplayView decouples the supernode if it is inserted inside another view hierarchy, this is // more difficult to guarantee with _ASDisplayLayer because CoreAnimation doesn't have a -didMoveToSuperlayer. @@ -1527,22 +1522,15 @@ static NSInteger incrementIfFound(NSInteger i) { // Do this before removing the view from the hierarchy, as the node will clear its supernode pointer when its view is removed from the hierarchy. // This call may result in the object being destroyed. [_supernode _removeSubnode:self]; - + if (shouldRemoveFromSuperviewOrSuperlayer) { ASPerformBlockOnMainThread(^{ ASDN::MutexLocker l(_propertyLock); - - if (movingBetweenNodes) { - _flags.isMovingBetweenNodes = YES; - } if (_flags.layerBacked) { [_layer removeFromSuperlayer]; } else { [_view removeFromSuperview]; } - if (movingBetweenNodes) { - _flags.isMovingBetweenNodes = NO; - } }); } } @@ -1982,14 +1970,6 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock) - (void)clearContents { // No-op if these haven't been created yet, as that guarantees they don't have contents that needs to be released. - { - ASDN::MutexLocker l(_propertyLock); - //Do not clear contents if we're mearly moving between nodes - if (_flags.isMovingBetweenNodes) { - return; - } - } - _layer.contents = nil; _placeholderLayer.contents = nil; _placeholderImage = nil; diff --git a/AsyncDisplayKit/Private/ASDisplayNodeInternal.h b/AsyncDisplayKit/Private/ASDisplayNodeInternal.h index 676000a9a1..8a3aa97b80 100644 --- a/AsyncDisplayKit/Private/ASDisplayNodeInternal.h +++ b/AsyncDisplayKit/Private/ASDisplayNodeInternal.h @@ -82,7 +82,6 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo unsigned isEnteringHierarchy:1; unsigned isExitingHierarchy:1; unsigned isInHierarchy:1; - unsigned isMovingBetweenNodes:1; unsigned visibilityNotificationsDisabled:VISIBILITY_NOTIFICATIONS_DISABLED_BITS; } _flags; From 057c431dfb9ad2816d6147a27bf6da843fc1338b Mon Sep 17 00:00:00 2001 From: Garrett Moon Date: Tue, 1 Mar 2016 16:46:03 -0800 Subject: [PATCH 2/2] Thanks @scottg, this is a better more generalized solution. --- AsyncDisplayKit/ASDisplayNode.mm | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index af1d9c9d6e..78641b039b 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -2083,7 +2083,13 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock) [self setDisplaySuspended:NO]; } else { [self setDisplaySuspended:YES]; - [self clearContents]; + //schedule clear contents on next runloop + dispatch_async(dispatch_get_main_queue(), ^{ + ASDN::MutexLocker l(_propertyLock); + if (ASInterfaceStateIncludesDisplay(_interfaceState) == NO) { + [self clearContents]; + } + }); } } else { // NOTE: This case isn't currently supported as setInterfaceState: isn't exposed externally, and all @@ -2095,7 +2101,13 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock) [ASDisplayNode scheduleNodeForRecursiveDisplay:self]; } else { [[self asyncLayer] cancelAsyncDisplay]; - [self clearContents]; + //schedule clear contents on next runloop + dispatch_async(dispatch_get_main_queue(), ^{ + ASDN::MutexLocker l(_propertyLock); + if (ASInterfaceStateIncludesDisplay(_interfaceState) == NO) { + [self clearContents]; + } + }); } } }