diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index 95a4a55f86..0bcf8afdb5 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -2505,7 +2505,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock) ASDisplayNodeAssert(!(_methodOverrides & ASDisplayNodeMethodOverrideLayoutSpecThatFits), @"Overwriting layoutSpecThatFits: and providing a layoutSpecBlock block is currently not supported"); ASDN::MutexLocker l(__instanceLock__); - _layoutSpecBlock = [layoutSpecBlock copy]; + _layoutSpecBlock = layoutSpecBlock; } - (ASLayoutSpecBlock)layoutSpecBlock diff --git a/AsyncDisplayKit/ASImageNode.mm b/AsyncDisplayKit/ASImageNode.mm index 1f0845b402..1aa0c22587 100644 --- a/AsyncDisplayKit/ASImageNode.mm +++ b/AsyncDisplayKit/ASImageNode.mm @@ -526,7 +526,7 @@ static ASDN::Mutex cacheLock; // Stash the block and call-site queue. We'll invoke it in -displayDidFinish. ASDN::MutexLocker l(__instanceLock__); if (_displayCompletionBlock != displayCompletionBlock) { - _displayCompletionBlock = [displayCompletionBlock copy]; + _displayCompletionBlock = displayCompletionBlock; } [self setNeedsDisplay]; diff --git a/AsyncDisplayKit/ASRunLoopQueue.mm b/AsyncDisplayKit/ASRunLoopQueue.mm index 42e5ea96e7..aac7ad1d17 100644 --- a/AsyncDisplayKit/ASRunLoopQueue.mm +++ b/AsyncDisplayKit/ASRunLoopQueue.mm @@ -164,7 +164,7 @@ static void runLoopSourceCallback(void *info) { if (self = [super init]) { _runLoop = runloop; _internalQueue = std::deque(); - _queueConsumer = [handlerBlock copy]; + _queueConsumer = handlerBlock; _batchSize = 1; _ensureExclusiveMembership = YES; diff --git a/AsyncDisplayKit/Details/Transactions/_ASAsyncTransaction.mm b/AsyncDisplayKit/Details/Transactions/_ASAsyncTransaction.mm index 82ddb2a686..55824942ce 100644 --- a/AsyncDisplayKit/Details/Transactions/_ASAsyncTransaction.mm +++ b/AsyncDisplayKit/Details/Transactions/_ASAsyncTransaction.mm @@ -36,7 +36,7 @@ NSInteger const ASDefaultTransactionPriority = 0; - (instancetype)initWithOperationCompletionBlock:(asyncdisplaykit_async_transaction_operation_completion_block_t)operationCompletionBlock { if ((self = [super init])) { - _operationCompletionBlock = [operationCompletionBlock copy]; + _operationCompletionBlock = operationCompletionBlock; } return self; } @@ -339,7 +339,7 @@ ASAsyncTransactionQueue & ASAsyncTransactionQueue::instance() callbackQueue = dispatch_get_main_queue(); } _callbackQueue = callbackQueue; - _completionBlock = [completionBlock copy]; + _completionBlock = completionBlock; _state = ATOMIC_VAR_INIT(ASAsyncTransactionStateOpen); } diff --git a/AsyncDisplayKit/Private/ASDisplayNode+AsyncDisplay.mm b/AsyncDisplayKit/Private/ASDisplayNode+AsyncDisplay.mm index 9fedcb1b4d..484b6b76a9 100644 --- a/AsyncDisplayKit/Private/ASDisplayNode+AsyncDisplay.mm +++ b/AsyncDisplayKit/Private/ASDisplayNode+AsyncDisplay.mm @@ -120,7 +120,7 @@ } } }; - [displayBlocks addObject:[pushAndDisplayBlock copy]]; + [displayBlocks addObject:pushAndDisplayBlock]; } // Recursively capture displayBlocks for all descendants. @@ -130,11 +130,16 @@ // If we pushed a transform, pop it by adding a display block that does nothing other than that. if (shouldDisplay) { - dispatch_block_t popBlock = ^{ - CGContextRef context = UIGraphicsGetCurrentContext(); - CGContextRestoreGState(context); - }; - [displayBlocks addObject:[popBlock copy]]; + // Since this block is pure, we can store it statically. + static dispatch_block_t popBlock; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + popBlock = ^{ + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextRestoreGState(context); + }; + }); + [displayBlocks addObject:popBlock]; } } @@ -252,7 +257,7 @@ }; } - return [displayBlock copy]; + return displayBlock; } - (void)displayAsyncLayer:(_ASDisplayLayer *)asyncLayer asynchronously:(BOOL)asynchronously