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

Commit 928c440

Browse files
author
Scott Goodson
committed
Several small optimizations, especially to _ASPendingState and other hot paths.
1 parent dd6ddfc commit 928c440

7 files changed

Lines changed: 48 additions & 28 deletions

File tree

AsyncDisplayKit/ASControlNode.m

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ - (id)init
7676
if (!(self = [super init]))
7777
return nil;
7878

79-
_controlEventDispatchTable = [[NSMutableDictionary alloc] initWithCapacity:kASControlNodeEventDispatchTableInitialCapacity]; // enough to handle common types without re-hashing the dictionary when adding entries.
8079
_enabled = YES;
8180

8281
// As we have no targets yet, we start off with user interaction off. When a target is added, it'll get turned back on.
@@ -214,6 +213,10 @@ - (void)addTarget:(id)target action:(SEL)action forControlEvents:(ASControlNodeE
214213
// Convert nil to [NSNull null] so that it can be used as a key for NSMapTable.
215214
if (!target)
216215
target = [NSNull null];
216+
217+
if (!_controlEventDispatchTable) {
218+
_controlEventDispatchTable = [[NSMutableDictionary alloc] initWithCapacity:kASControlNodeEventDispatchTableInitialCapacity]; // enough to handle common types without re-hashing the dictionary when adding entries.
219+
}
217220

218221
// Enumerate the events in the mask, adding the target-action pair for each control event included in controlEventMask
219222
_ASEnumerateControlEventsIncludedInMaskWithBlock(controlEventMask, ^

AsyncDisplayKit/ASDisplayNode.mm

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,9 +1470,9 @@ - (BOOL)_pendingDisplayNodesHaveFinished
14701470
}
14711471

14721472
// Helper method to summarize whether or not the node run through the display process
1473-
- (BOOL)_implementsDisplay
1473+
- (BOOL)__implementsDisplay
14741474
{
1475-
return _flags.implementsDrawRect == YES || _flags.implementsImageDisplay == YES;
1475+
return _flags.implementsDrawRect == YES || _flags.implementsImageDisplay == YES || self.shouldRasterizeDescendants;
14761476
}
14771477

14781478
- (void)_setupPlaceholderLayer
@@ -1502,7 +1502,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
15021502
// (even a runloop observer at a late call order will not stop the next frame from compositing, showing placeholders).
15031503

15041504
ASDisplayNode *node = [layer asyncdisplaykit_node];
1505-
if (!layer.contents && [node _implementsDisplay]) {
1505+
if (!layer.contents && [node __implementsDisplay]) {
15061506
// For layers that do get displayed here, this immediately kicks off the work on the concurrent -[_ASDisplayLayer displayQueue].
15071507
// At the same time, it creates an associated _ASAsyncTransaction, which we can use to block on display completion. See ASDisplayNode+AsyncDisplay.mm.
15081508
[layer displayIfNeeded];
@@ -2148,7 +2148,7 @@ - (void)setDisplaySuspended:(BOOL)flag
21482148

21492149
self.asyncLayer.displaySuspended = flag;
21502150

2151-
if ([self _implementsDisplay]) {
2151+
if ([self __implementsDisplay]) {
21522152
if (flag) {
21532153
[_supernode subnodeDisplayDidFinish:self];
21542154
} else {

AsyncDisplayKit/ASPagerNode.m

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@ @implementation ASPagerNode
2020

2121
- (instancetype)init
2222
{
23-
_flowLayout = [[UICollectionViewFlowLayout alloc] init];
24-
_flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
25-
_flowLayout.minimumInteritemSpacing = 0;
26-
_flowLayout.minimumLineSpacing = 0;
23+
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
24+
flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
25+
flowLayout.minimumInteritemSpacing = 0;
26+
flowLayout.minimumLineSpacing = 0;
2727

28-
self = [super initWithCollectionViewLayout:_flowLayout];
28+
self = [super initWithCollectionViewLayout:flowLayout];
2929
if (self != nil) {
30+
_flowLayout = flowLayout;
3031
}
3132
return self;
3233
}

AsyncDisplayKit/ASTextNode.mm

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ @implementation ASTextNode {
9797

9898
#pragma mark - NSObject
9999

100+
static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
101+
100102
- (instancetype)init
101103
{
102104
if (self = [super init]) {
@@ -120,7 +122,7 @@ - (instancetype)init
120122
self.opaque = NO;
121123
self.backgroundColor = [UIColor clearColor];
122124

123-
self.linkAttributeNames = @[ NSLinkAttributeName ];
125+
self.linkAttributeNames = DefaultLinkAttributeNames;
124126

125127
// Accessibility
126128
self.isAccessibilityElement = YES;

AsyncDisplayKit/Private/ASDisplayNode+AsyncDisplay.mm

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,6 @@ - (void)_recursivelyRasterizeSelfAndSublayersWithIsCancelledBlock:(asdisplaynode
175175

176176
- (asyncdisplaykit_async_transaction_operation_block_t)_displayBlockWithAsynchronous:(BOOL)asynchronous isCancelledBlock:(asdisplaynode_iscancelled_block_t)isCancelledBlock rasterizing:(BOOL)rasterizing
177177
{
178-
id nodeClass = [self class];
179-
180178
asyncdisplaykit_async_transaction_operation_block_t displayBlock = nil;
181179

182180
ASDisplayNodeAssert(rasterizing || !(_hierarchyState & ASHierarchyStateRasterized), @"Rasterized descendants should never display unless being drawn into the rasterized container.");
@@ -235,7 +233,7 @@ - (asyncdisplaykit_async_transaction_operation_block_t)_displayBlockWithAsynchro
235233

236234
ASDN_DELAY_FOR_DISPLAY();
237235

238-
UIImage *result = [nodeClass displayWithParameters:drawParameters isCancelled:isCancelledBlock];
236+
UIImage *result = [[self class] displayWithParameters:drawParameters isCancelled:isCancelledBlock];
239237
__ASDisplayLayerDecrementConcurrentDisplayCount(asynchronous, rasterizing);
240238
return result;
241239
};
@@ -265,7 +263,7 @@ - (asyncdisplaykit_async_transaction_operation_block_t)_displayBlockWithAsynchro
265263
UIGraphicsBeginImageContextWithOptions(bounds.size, opaque, contentsScaleForDisplay);
266264
}
267265

268-
[nodeClass drawRect:bounds withParameters:drawParameters isCancelled:isCancelledBlock isRasterizing:rasterizing];
266+
[[self class] drawRect:bounds withParameters:drawParameters isCancelled:isCancelledBlock isRasterizing:rasterizing];
269267

270268
if (isCancelledBlock()) {
271269
if (!rasterizing) {

AsyncDisplayKit/Private/ASDisplayNodeInternal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ typedef NS_OPTIONS(NSUInteger, ASDisplayNodeMethodOverrides)
144144
// Call didExitHierarchy if necessary and set inHierarchy = NO if visibility notifications are enabled on all of its parents
145145
- (void)__exitHierarchy;
146146

147+
// Helper method to summarize whether or not the node run through the display process
148+
- (BOOL)__implementsDisplay;
149+
147150
// Display the node's view/layer immediately on the current thread, bypassing the background thread rendering. Will be deprecated.
148151
- (void)displayImmediately;
149152

AsyncDisplayKit/Private/_ASPendingState.m

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -135,19 +135,24 @@ @implementation _ASPendingState
135135
@synthesize borderColor=borderColor;
136136
@synthesize asyncdisplaykit_asyncTransactionContainer=asyncTransactionContainer;
137137

138+
139+
static CGColorRef blackColorRef = NULL;
140+
static UIColor *defaultTintColor = nil;
141+
138142
- (id)init
139143
{
140144
if (!(self = [super init]))
141145
return nil;
142146

143-
// Default UIKit color is an RGB color
144-
static CGColorRef black;
147+
145148
static dispatch_once_t onceToken;
146149
dispatch_once(&onceToken, ^{
150+
// Default UIKit color is an RGB color
147151
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
148-
black = CGColorCreate(colorSpace, (CGFloat[]){0,0,0,1} );
149-
CFRetain(black);
152+
blackColorRef = CGColorCreate(colorSpace, (CGFloat[]){0,0,0,1} );
153+
CFRetain(blackColorRef);
150154
CGColorSpaceRelease(colorSpace);
155+
defaultTintColor = [UIColor colorWithRed:0.0 green:0.478 blue:1.0 alpha:1.0];
151156
});
152157

153158
// Set defaults, these come from the defaults specified in CALayer and UIView
@@ -156,7 +161,7 @@ - (id)init
156161
frame = CGRectZero;
157162
bounds = CGRectZero;
158163
backgroundColor = nil;
159-
tintColor = [UIColor colorWithRed:0.0 green:0.478 blue:1.0 alpha:1.0];
164+
tintColor = defaultTintColor;
160165
contents = nil;
161166
isHidden = NO;
162167
needsDisplayOnBoundsChange = NO;
@@ -172,14 +177,12 @@ - (id)init
172177
transform = CATransform3DIdentity;
173178
sublayerTransform = CATransform3DIdentity;
174179
userInteractionEnabled = YES;
175-
CFRetain(black);
176-
shadowColor = black;
180+
shadowColor = blackColorRef;
177181
shadowOpacity = 0.0;
178182
shadowOffset = CGSizeMake(0, -3);
179183
shadowRadius = 3;
180184
borderWidth = 0;
181-
CFRetain(black);
182-
borderColor = black;
185+
borderColor = blackColorRef;
183186
isAccessibilityElement = NO;
184187
accessibilityLabel = nil;
185188
accessibilityHint = nil;
@@ -376,7 +379,9 @@ - (void)setShadowColor:(CGColorRef)color
376379
return;
377380
}
378381

379-
CGColorRelease(shadowColor);
382+
if (shadowColor != blackColorRef) {
383+
CGColorRelease(shadowColor);
384+
}
380385
shadowColor = color;
381386
CGColorRetain(shadowColor);
382387

@@ -413,7 +418,9 @@ - (void)setBorderColor:(CGColorRef)color
413418
return;
414419
}
415420

416-
CGColorRelease(borderColor);
421+
if (borderColor != blackColorRef) {
422+
CGColorRelease(borderColor);
423+
}
417424
borderColor = color;
418425
CGColorRetain(borderColor);
419426

@@ -1002,8 +1009,14 @@ + (_ASPendingState *)pendingViewStateFromView:(UIView *)view
10021009
- (void)dealloc
10031010
{
10041011
CGColorRelease(backgroundColor);
1005-
CGColorRelease(shadowColor);
1006-
CGColorRelease(borderColor);
1012+
1013+
if (shadowColor != blackColorRef) {
1014+
CGColorRelease(shadowColor);
1015+
}
1016+
1017+
if (borderColor != blackColorRef) {
1018+
CGColorRelease(borderColor);
1019+
}
10071020
}
10081021

10091022
@end

0 commit comments

Comments
 (0)