Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ASTableNode & ASCollectionNode] Keepalive reference for node if their view is necessarily alive (has a superview). #793

Merged
merged 9 commits into from
Feb 9, 2018
7 changes: 7 additions & 0 deletions Source/ASCollectionNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionVi
return self;
}

- (void)dealloc
{
if ([self isNodeLoaded]) {
ASDisplayNodeAssert(self.view.superview == nil, @"Node's view should be removed from hierarchy.");
}
}

#pragma mark ASDisplayNode

- (void)didLoad
Expand Down
21 changes: 20 additions & 1 deletion Source/ASCollectionView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,12 @@ @interface ASCollectionView () <ASRangeControllerDataSource, ASRangeControllerDe
* Counter used to keep track of nested batch updates.
*/
NSInteger _batchUpdateCount;


/**
* Keep a strong reference to node till view is ready to release.
*/
ASCollectionNode *_keepalive_node;

struct {
unsigned int scrollViewDidScroll:1;
unsigned int scrollViewWillBeginDragging:1;
Expand Down Expand Up @@ -2250,6 +2255,20 @@ - (void)didMoveToWindow
}
}

- (void)willMoveToSuperview:(UIView *)newSuperview
{
if (self.superview == nil && newSuperview != nil) {
_keepalive_node = self.collectionNode;
}
}

- (void)didMoveToSuperview
{
if (self.superview == nil) {
_keepalive_node = nil;
}
}

#pragma mark ASCALayerExtendedDelegate

/**
Expand Down
7 changes: 7 additions & 0 deletions Source/ASTableNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ - (instancetype)init
return [self initWithStyle:UITableViewStylePlain];
}

- (void)dealloc
{
if ([self isNodeLoaded]) {
ASDisplayNodeAssert(self.view.superview == nil, @"Node's view should be removed from hierarchy.");
}
}

#pragma mark ASDisplayNode

- (void)didLoad
Expand Down
21 changes: 20 additions & 1 deletion Source/ASTableView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,12 @@ @interface ASTableView () <ASRangeControllerDataSource, ASRangeControllerDelegat
* Counter used to keep track of nested batch updates.
*/
NSInteger _batchUpdateCount;


/**
* Keep a strong reference to node till view is ready to release.
*/
ASTableNode *_keepalive_node;

struct {
unsigned int scrollViewDidScroll:1;
unsigned int scrollViewWillBeginDragging:1;
Expand Down Expand Up @@ -1913,4 +1918,18 @@ - (void)didMoveToWindow
}
}

- (void)willMoveToSuperview:(UIView *)newSuperview
{
if (self.superview == nil && newSuperview != nil) {
_keepalive_node = self.tableNode;
}
}

- (void)didMoveToSuperview
{
if (self.superview == nil) {
_keepalive_node = nil;
}
}

@end
1 change: 1 addition & 0 deletions Tests/ASCollectionViewTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,7 @@ - (void)testInitialRangeBounds
for (NSInteger i = 0; i < c; i++) {
NSIndexPath *ip = [NSIndexPath indexPathForItem:i inSection:s];
ASCellNode *node = [cn nodeForItemAtIndexPath:ip];
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.001]];
if (node.inPreloadState) {
CGRect frame = [cn.view layoutAttributesForItemAtIndexPath:ip].frame;
r = CGRectUnion(r, frame);
Expand Down