From d45db5ac326dd415b4d528fbff3ac29de782d674 Mon Sep 17 00:00:00 2001 From: Scott Goodson Date: Sat, 9 Jan 2016 20:44:24 -0800 Subject: [PATCH] Disable creation of backing ASTable/CollectionNode for the *View varients (retain cycle). --- AsyncDisplayKit/ASCollectionView.mm | 10 +++++++++- AsyncDisplayKit/ASTableNode.m | 6 ++++-- AsyncDisplayKit/ASTableView.mm | 12 ++++++++++-- AsyncDisplayKit/Details/ASRangeController.h | 2 ++ examples/ASTableViewStressTest/Sample/AppDelegate.m | 5 +++++ 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index f42ec5b6b0..4124f1a03b 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -150,7 +150,10 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; if (!ownedByNode) { // See commentary at the definition of .strongCollectionNode for why we create an ASCollectionNode. - ASCollectionNode *collectionNode = [[ASCollectionNode alloc] _initWithCollectionView:self]; + // FIXME: The _view pointer of the node retains us, but the node will die immediately if we don't + // retain it. At the moment there isn't a great solution to this, so we can't yet move our core + // logic to ASCollectionNode (required to have a shared superclass with ASTable*). + ASCollectionNode *collectionNode = nil; //[[ASCollectionNode alloc] _initWithCollectionView:self]; self.strongCollectionNode = collectionNode; } @@ -349,6 +352,11 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; return [[_dataController nodeAtIndexPath:indexPath] calculatedSize]; } +- (NSArray *> *)completedNodes +{ + return [_dataController completedNodes]; +} + - (ASCellNode *)nodeForItemAtIndexPath:(NSIndexPath *)indexPath { return [_dataController nodeAtIndexPath:indexPath]; diff --git a/AsyncDisplayKit/ASTableNode.m b/AsyncDisplayKit/ASTableNode.m index f81623aeb7..a54f0bf11e 100644 --- a/AsyncDisplayKit/ASTableNode.m +++ b/AsyncDisplayKit/ASTableNode.m @@ -31,8 +31,10 @@ - (instancetype)_initWithTableView:(ASTableView *)tableView { - if (self = [super initWithViewBlock:^UIView *{ return tableView; }]) { - __unused ASTableView *tableView = [self view]; + // Avoid a retain cycle. In this case, the ASTableView is creating us, and strongly retains us. + ASTableView * __weak weakTableView = tableView; + if (self = [super initWithViewBlock:^UIView *{ return weakTableView; }]) { + __unused __weak ASTableView *view = [self view]; return self; } return nil; diff --git a/AsyncDisplayKit/ASTableView.mm b/AsyncDisplayKit/ASTableView.mm index 7632a7c63d..6bb97782f9 100644 --- a/AsyncDisplayKit/ASTableView.mm +++ b/AsyncDisplayKit/ASTableView.mm @@ -198,14 +198,17 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; } if (!dataControllerClass) { - dataControllerClass = [self.class dataControllerClass]; + dataControllerClass = [[self class] dataControllerClass]; } [self configureWithDataControllerClass:dataControllerClass]; if (!ownedByNode) { // See commentary at the definition of .strongTableNode for why we create an ASTableNode. - ASTableNode *tableNode = [[ASTableNode alloc] _initWithTableView:self]; + // FIXME: The _view pointer of the node retains us, but the node will die immediately if we don't + // retain it. At the moment there isn't a great solution to this, so we can't yet move our core + // logic to ASTableNode (required to have a shared superclass with ASCollection*). + ASTableNode *tableNode = nil; //[[ASTableNode alloc] _initWithTableView:self]; self.strongTableNode = tableNode; } @@ -333,6 +336,11 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; [self setTuningParameters:tuningParameters forRangeType:ASLayoutRangeTypeDisplay]; } +- (NSArray *> *)completedNodes +{ + return [_dataController completedNodes]; +} + - (ASCellNode *)nodeForRowAtIndexPath:(NSIndexPath *)indexPath { return [_dataController nodeAtIndexPath:indexPath]; diff --git a/AsyncDisplayKit/Details/ASRangeController.h b/AsyncDisplayKit/Details/ASRangeController.h index c8dee77e11..74061f8806 100644 --- a/AsyncDisplayKit/Details/ASRangeController.h +++ b/AsyncDisplayKit/Details/ASRangeController.h @@ -117,6 +117,8 @@ NS_ASSUME_NONNULL_BEGIN - (ASDisplayNode *)rangeController:(ASRangeController *)rangeController nodeAtIndexPath:(NSIndexPath *)indexPath; +- (NSArray *> *)completedNodes; + @end /** diff --git a/examples/ASTableViewStressTest/Sample/AppDelegate.m b/examples/ASTableViewStressTest/Sample/AppDelegate.m index a8d611608c..4bc15faea9 100644 --- a/examples/ASTableViewStressTest/Sample/AppDelegate.m +++ b/examples/ASTableViewStressTest/Sample/AppDelegate.m @@ -13,10 +13,15 @@ #import "ViewController.h" +#import +#import + @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [ASDisplayNode setShouldUseNewRenderingRange:YES]; + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; self.window.rootViewController = [[UINavigationController alloc] init];