diff --git a/AsyncDisplayKit/ASMultiplexImageNode.mm b/AsyncDisplayKit/ASMultiplexImageNode.mm index e521cb83d5..7fcad269a3 100644 --- a/AsyncDisplayKit/ASMultiplexImageNode.mm +++ b/AsyncDisplayKit/ASMultiplexImageNode.mm @@ -452,9 +452,13 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent #pragma mark - +/** + @note: This should be called without _downloadIdentifierLock held. We will lock + super to read our interface state and it's best to avoid acquiring both locks. + */ - (void)_updateProgressImageBlockOnDownloaderIfNeeded { - // Read our interface state so that we don't lock super while holding our lock. + // Read our interface state before locking so that we don't lock super while holding our lock. ASInterfaceState interfaceState = self.interfaceState; ASDN::MutexLocker l(_downloadIdentifierLock); diff --git a/AsyncDisplayKit/ASNetworkImageNode.mm b/AsyncDisplayKit/ASNetworkImageNode.mm index 8624be9fba..f75a609183 100755 --- a/AsyncDisplayKit/ASNetworkImageNode.mm +++ b/AsyncDisplayKit/ASNetworkImageNode.mm @@ -213,8 +213,8 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; { [super visibilityDidChange:isVisible]; - ASDN::MutexLocker l(_lock); if (_downloaderImplementsSetPriority) { + ASDN::MutexLocker l(_lock); if (_downloadIdentifier != nil) { if (isVisible) { [_downloader setPriority:ASImageDownloaderPriorityVisible withDownloadIdentifier:_downloadIdentifier]; @@ -254,14 +254,22 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; #pragma mark - Private methods -- only call with lock. +/** + @note: This should be called without _lock held. We will lock + super to read our interface state and it's best to avoid acquiring both locks. + */ - (void)_updateProgressImageBlockOnDownloaderIfNeeded { + // Read our interface state before locking so that we don't lock super while holding our lock. + ASInterfaceState interfaceState = self.interfaceState; + ASDN::MutexLocker l(_lock); + if (!_downloaderImplementsSetProgress || _downloadIdentifier == nil) { return; } ASImageDownloaderProgressImage progress = nil; - if (ASInterfaceStateIncludesVisible(self.interfaceState)) { + if (ASInterfaceStateIncludesVisible(interfaceState)) { __weak __typeof__(self) weakSelf = self; progress = ^(UIImage * _Nonnull progressImage, id _Nullable downloadIdentifier) { __typeof__(self) strongSelf = weakSelf;