From 7ef6c0ff2ccaf33d480be422cd02456ad28008ec Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Thu, 1 Sep 2016 12:04:21 -0700 Subject: [PATCH] Fix using ASDisplayNodePerformBlockOnEveryNode if node is loaded and has shouldRasterizeDescendants enabled (#2179) We don't call the block on every subnode if the node that is passed in ASDisplayNodePerformBlockOnEveryNode has shouldRasterizeDescendants enabled as it tries to iterate through the sublayer hierarchy, but there are no sublayers --- AsyncDisplayKit/ASDisplayNodeExtras.mm | 2 +- AsyncDisplayKitTests/ASDisplayNodeTests.m | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/AsyncDisplayKit/ASDisplayNodeExtras.mm b/AsyncDisplayKit/ASDisplayNodeExtras.mm index 19f199bd5b..8090d37b7e 100644 --- a/AsyncDisplayKit/ASDisplayNodeExtras.mm +++ b/AsyncDisplayKit/ASDisplayNodeExtras.mm @@ -54,7 +54,7 @@ extern void ASDisplayNodePerformBlockOnEveryNode(CALayer *layer, ASDisplayNode * layer = node.layer; } - if (layer) { + if (layer && node.shouldRasterizeDescendants == NO) { /// NOTE: The docs say `sublayers` returns a copy, but it does not. /// See: http://stackoverflow.com/questions/14854480/collection-calayerarray-0x1ed8faa0-was-mutated-while-being-enumerated for (CALayer *sublayer in [[layer sublayers] copy]) { diff --git a/AsyncDisplayKitTests/ASDisplayNodeTests.m b/AsyncDisplayKitTests/ASDisplayNodeTests.m index 0e148e2908..78ff9f887c 100644 --- a/AsyncDisplayKitTests/ASDisplayNodeTests.m +++ b/AsyncDisplayKitTests/ASDisplayNodeTests.m @@ -1964,4 +1964,26 @@ static bool stringContainsPointer(NSString *description, id p) { XCTAssertNoThrow([nodeView removeFromSuperview]); } + +- (void)testThatSubnodeGetsInterfaceStateSetIfRasterized +{ + ASTestDisplayNode *node = [[ASTestDisplayNode alloc] init]; + node.name = @"Node"; + node.shouldRasterizeDescendants = YES; + + ASTestDisplayNode *subnode = [[ASTestDisplayNode alloc] init]; + subnode.name = @"Subnode"; + [node addSubnode:subnode]; + + [node view]; // Node needs to be loaded + + [node enterInterfaceState:ASInterfaceStateFetchData]; + + + XCTAssertTrue((node.interfaceState & ASInterfaceStateFetchData) == ASInterfaceStateFetchData); + XCTAssertTrue((subnode.interfaceState & ASInterfaceStateFetchData) == ASInterfaceStateFetchData); + XCTAssertTrue(node.hasFetchedData); + XCTAssertTrue(subnode.hasFetchedData); +} + @end