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

Commit 9b9d8bc

Browse files
committed
Merge pull request #1016 from facebook/RasterizationUnloadingNodes
Ensure that the uncommon __unloadNode codepath does not unintentionally trigger node removal.
2 parents cc15d74 + df3ce78 commit 9b9d8bc

4 files changed

Lines changed: 31 additions & 3 deletions

File tree

AsyncDisplayKit/ASDisplayNode.mm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,9 @@ - (void)dealloc
352352
- (void)__unloadNode
353353
{
354354
ASDisplayNodeAssertThreadAffinity(self);
355+
ASDisplayNodeAssert([self isNodeLoaded], @"Implementation shouldn't call __unloadNode if not loaded: %@", self);
355356
ASDN::MutexLocker l(_propertyLock);
356-
357+
357358
if (_flags.layerBacked)
358359
_pendingViewState = [_ASPendingState pendingViewStateFromLayer:_layer];
359360
else

AsyncDisplayKit/Details/_ASDisplayView.mm

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,11 @@ - (void)didMoveToSuperview
151151
needsSupernodeRemoval = YES;
152152
}
153153
} else {
154-
// If supernode is loaded but our superview is nil, the user manually removed us, so disconnect supernode.
155-
needsSupernodeRemoval = supernodeLoaded;
154+
// If supernode is loaded but our superview is nil, the user likely manually removed us, so disconnect supernode.
155+
// The unlikely alternative: we are in __unloadNode, with shouldRasterizeSubnodes just having been turned on.
156+
// In the latter case, we don't want to disassemble the node hierarchy because all views are intentionally being destroyed.
157+
BOOL nodeIsRasterized = ((_node.hierarchyState & ASHierarchyStateRasterized) == ASHierarchyStateRasterized);
158+
needsSupernodeRemoval = (supernodeLoaded && !nodeIsRasterized);
156159
}
157160

158161
if (needsSupernodeRemoval) {

AsyncDisplayKit/Private/_ASPendingState.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,8 +798,13 @@ - (void)applyToView:(UIView *)view
798798
view.accessibilityIdentifier = accessibilityIdentifier;
799799
}
800800

801+
// FIXME: Make this more efficient by tracking which properties are set rather than reading everything.
801802
+ (_ASPendingState *)pendingViewStateFromLayer:(CALayer *)layer
802803
{
804+
if (!layer) {
805+
return nil;
806+
}
807+
803808
_ASPendingState *pendingState = [[_ASPendingState alloc] init];
804809

805810
pendingState.anchorPoint = layer.anchorPoint;
@@ -877,8 +882,13 @@ + (_ASPendingState *)pendingViewStateFromLayer:(CALayer *)layer
877882
return pendingState;
878883
}
879884

885+
// FIXME: Make this more efficient by tracking which properties are set rather than reading everything.
880886
+ (_ASPendingState *)pendingViewStateFromView:(UIView *)view
881887
{
888+
if (!view) {
889+
return nil;
890+
}
891+
882892
_ASPendingState *pendingState = [[_ASPendingState alloc] init];
883893

884894
CALayer *layer = view.layer;

examples/SocialAppLayout/Sample/ViewController.m

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,18 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger
134134
return _socialAppDataSource.count;
135135
}
136136

137+
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
138+
{
139+
PostNode *postNode = (PostNode *)[_tableView nodeForRowAtIndexPath:indexPath];
140+
Post *post = _socialAppDataSource[indexPath.row];
141+
142+
BOOL shouldRasterize = postNode.shouldRasterizeDescendants;
143+
shouldRasterize = !shouldRasterize;
144+
postNode.shouldRasterizeDescendants = shouldRasterize;
145+
146+
NSLog(@"%@ rasterization for %@'s post: %@", shouldRasterize ? @"Enabling" : @"Disabling", post.name, postNode);
147+
148+
[tableView deselectRowAtIndexPath:indexPath animated:YES];
149+
}
150+
137151
@end

0 commit comments

Comments
 (0)