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

Commit 06688f7

Browse files
author
Scott Goodson
committed
Release the lock before setting supernode pointer to nil, in case we are deallocated.
1 parent 841bed6 commit 06688f7

1 file changed

Lines changed: 19 additions & 14 deletions

File tree

AsyncDisplayKit/ASDisplayNode.mm

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,28 +1220,33 @@ - (void)_removeSubnode:(ASDisplayNode *)subnode
12201220
- (void)removeFromSupernode
12211221
{
12221222
ASDisplayNodeAssertThreadAffinity(self);
1223-
ASDN::MutexLocker l(_propertyLock);
1224-
if (!_supernode)
1225-
return;
1226-
1227-
// Check to ensure that our view or layer is actually inside of our supernode; otherwise, don't remove it.
1228-
// Though _ASDisplayView decouples the supernode if it is inserted inside another view hierarchy, this is
1229-
// more difficult to guarantee with _ASDisplayLayer because CoreAnimation doesn't have a -didMoveToSuperlayer.
12301223
BOOL shouldRemoveFromSuperviewOrSuperlayer = NO;
12311224

1232-
if (self.nodeLoaded && _supernode.nodeLoaded) {
1233-
if (_flags.layerBacked || _supernode.layerBacked) {
1234-
shouldRemoveFromSuperviewOrSuperlayer = (_layer.superlayer == _supernode.layer);
1235-
} else {
1236-
shouldRemoveFromSuperviewOrSuperlayer = (_view.superview == _supernode.view);
1225+
{
1226+
ASDN::MutexLocker l(_propertyLock);
1227+
if (!_supernode)
1228+
return;
1229+
1230+
// Check to ensure that our view or layer is actually inside of our supernode; otherwise, don't remove it.
1231+
// Though _ASDisplayView decouples the supernode if it is inserted inside another view hierarchy, this is
1232+
// more difficult to guarantee with _ASDisplayLayer because CoreAnimation doesn't have a -didMoveToSuperlayer.
1233+
1234+
if (self.nodeLoaded && _supernode.nodeLoaded) {
1235+
if (_flags.layerBacked || _supernode.layerBacked) {
1236+
shouldRemoveFromSuperviewOrSuperlayer = (_layer.superlayer == _supernode.layer);
1237+
} else {
1238+
shouldRemoveFromSuperviewOrSuperlayer = (_view.superview == _supernode.view);
1239+
}
12371240
}
12381241
}
1239-
1242+
12401243
// 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.
1244+
// This call may result in the object being destroyed.
12411245
[_supernode _removeSubnode:self];
12421246

12431247
if (shouldRemoveFromSuperviewOrSuperlayer) {
12441248
ASPerformBlockOnMainThread(^{
1249+
ASDN::MutexLocker l(_propertyLock);
12451250
if (_flags.layerBacked) {
12461251
[_layer removeFromSuperlayer];
12471252
} else {
@@ -1869,7 +1874,7 @@ - (void)layout
18691874
ASDisplayNode *subnode = nil;
18701875
CGRect subnodeFrame = CGRectZero;
18711876
for (ASLayout *subnodeLayout in _layout.sublayouts) {
1872-
ASDisplayNodeAssert([_subnodes containsObject:subnodeLayout.layoutableObject], @"Cached sublayouts must only contain subnodes' layout.");
1877+
ASDisplayNodeAssert([_subnodes containsObject:subnodeLayout.layoutableObject], @"Cached sublayouts must only contain subnodes' layout. self = %@, subnodes = %@", self, _subnodes);
18731878
CGPoint adjustedOrigin = subnodeLayout.position;
18741879
if (isfinite(adjustedOrigin.x) == NO) {
18751880
ASDisplayNodeAssert(0, @"subnodeLayout has an invalid position");

0 commit comments

Comments
 (0)