diff --git a/AsyncDisplayKit/ASImageNode.mm b/AsyncDisplayKit/ASImageNode.mm index 3864ca5ad6..9f67f03d2e 100644 --- a/AsyncDisplayKit/ASImageNode.mm +++ b/AsyncDisplayKit/ASImageNode.mm @@ -154,20 +154,27 @@ - (UIImage *)displayWithParameters:(_ASImageNodeDrawParameters *)parameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelled { - ASDN::MutexLocker l(_imageLock); - UIImage *image = _image; - if (!image) { - return nil; + UIImage *image; + BOOL cropEnabled; + CGFloat contentsScale; + CGRect cropDisplayBounds; + CGRect cropRect; + asimagenode_modification_block_t imageModificationBlock; + + { + ASDN::MutexLocker l(_imageLock); + image = _image; + if (!image) { + return nil; + } + + cropEnabled = _cropEnabled; + contentsScale = _contentsScaleForDisplay; + cropDisplayBounds = _cropDisplayBounds; + cropRect = _cropRect; + imageModificationBlock = _imageModificationBlock; } - BOOL cropEnabled = _cropEnabled; - CGFloat contentsScale = _contentsScaleForDisplay; - CGRect cropDisplayBounds = _cropDisplayBounds; - CGRect cropRect = _cropRect; - asimagenode_modification_block_t imageModificationBlock = _imageModificationBlock; - - ASDN::MutexUnlocker u(_imageLock); - ASDisplayNodeContextModifier preContextBlock = self.willDisplayNodeContentWithRenderingContext; ASDisplayNodeContextModifier postContextBlock = self.didDisplayNodeContentWithRenderingContext; @@ -292,7 +299,6 @@ // If we've got a block to perform after displaying, do it. if (image && displayCompletionBlock) { - // FIXME: _displayCompletionBlock is not protected by lock displayCompletionBlock(NO); ASDN::MutexLocker l(_imageLock); @@ -311,7 +317,6 @@ } // Stash the block and call-site queue. We'll invoke it in -displayDidFinish. - // FIXME: _displayCompletionBlock not protected by lock ASDN::MutexLocker l(_imageLock); if (_displayCompletionBlock != displayCompletionBlock) { _displayCompletionBlock = [displayCompletionBlock copy]; diff --git a/AsyncDisplayKit/ASTextNode.mm b/AsyncDisplayKit/ASTextNode.mm index 2741dda576..7e37477e7c 100644 --- a/AsyncDisplayKit/ASTextNode.mm +++ b/AsyncDisplayKit/ASTextNode.mm @@ -217,7 +217,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; #pragma mark - Renderer Management -//only safe to call on the main thread +//only safe to call on the main thread because self.bounds is only safe to call on the main thread one our node is loaded - (ASTextKitRenderer *)_renderer { return [self _rendererWithBounds:self.bounds]; @@ -415,7 +415,8 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; ASTextKitRenderer *renderer = [self _rendererWithBounds:parameters.bounds]; UIEdgeInsets shadowPadding = [self shadowPaddingWithRenderer:renderer]; - CGPoint textOrigin = CGPointMake(parameters.bounds.origin.x - shadowPadding.left, parameters.bounds.origin.y - shadowPadding.top); + CGPoint boundsOrigin = parameters.bounds.origin; + CGPoint textOrigin = CGPointMake(boundsOrigin.x - shadowPadding.left, boundsOrigin.y - shadowPadding.top); // Fill background if (!isRasterizing) { @@ -998,7 +999,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; } } -//only safe to call on main thread +//only safe to call on main thread, because [self _renderer] is only safe to call on the main thread - (UIEdgeInsets)shadowPadding { return [self shadowPaddingWithRenderer:[self _renderer]]; diff --git a/AsyncDisplayKit/Private/ASDisplayNode+AsyncDisplay.mm b/AsyncDisplayKit/Private/ASDisplayNode+AsyncDisplay.mm index 24100027a9..aa0982b77a 100644 --- a/AsyncDisplayKit/Private/ASDisplayNode+AsyncDisplay.mm +++ b/AsyncDisplayKit/Private/ASDisplayNode+AsyncDisplay.mm @@ -239,6 +239,8 @@ static void __ASDisplayLayerDecrementConcurrentDisplayCount(BOOL displayIsAsync, ASDN_DELAY_FOR_DISPLAY(); UIImage *result = nil; + //We can't call _willDisplayNodeContentWithRenderingContext or _didDisplayNodeContentWithRenderingContext because we don't + //have a context. We rely on implementors of displayWithParameters:isCancelled: to call if (_flags.implementsInstanceImageDisplay) { result = [self displayWithParameters:drawParameters isCancelled:isCancelledBlock]; } else {