Skip to content

Commit

Permalink
A couple performance tweaks for animated images
Browse files Browse the repository at this point in the history
  • Loading branch information
garrettmoon committed Oct 23, 2017
1 parent 63842e1 commit 7040a11
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 41 deletions.
8 changes: 8 additions & 0 deletions Source/ASImageNode+AnimatedImage.mm
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ - (void)_locked_setAnimatedImage:(id <ASAnimatedImageProtocol>)animatedImage
if (ASObjectIsEqual(_animatedImage, animatedImage)) {
return;
}

if (animatedImage == nil) {
// Animated image can take while to dealloc, do it off the main queue
__block id <ASAnimatedImageProtocol>deallocImage = _animatedImage;
ASPerformBlockOnBackgroundThread(^{
deallocImage = nil;
});
}

id <ASAnimatedImageProtocol> previousAnimatedImage = _animatedImage;
_animatedImage = animatedImage;
Expand Down
93 changes: 52 additions & 41 deletions Source/ASNetworkImageNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -696,50 +696,61 @@ - (void)_lazilyLoadImageIfNecessary
} else {
__weak __typeof__(self) weakSelf = self;
auto finished = ^(id <ASImageContainerProtocol>imageContainer, NSError *error, id downloadIdentifier) {

__typeof__(self) strongSelf = weakSelf;
if (strongSelf == nil) {
return;
}

as_log_verbose(ASImageLoadingLog(), "Downloaded image for %@ img: %@ urls: %@", self, [imageContainer asdk_image], URLs);

// Grab the lock for the rest of the block
ASDN::MutexLocker l(strongSelf->__instanceLock__);

//Getting a result back for a different download identifier, download must not have been successfully canceled
if (ASObjectIsEqual(strongSelf->_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) {
return;
}
ASPerformBlockOnBackgroundThread(^{
__typeof__(self) strongSelf = weakSelf;
if (strongSelf == nil) {
return;
}

//No longer in preload range, no point in setting the results (they won't be cleared in exit preload range)
if (ASInterfaceStateIncludesPreload(self->_interfaceState) == NO) {
return;
}

if (imageContainer != nil) {
[strongSelf _locked_setCurrentImageQuality:1.0];
if ([imageContainer asdk_animatedImageData] && strongSelf->_downloaderFlags.downloaderImplementsAnimatedImage) {
id animatedImage = [strongSelf->_downloader animatedImageWithData:[imageContainer asdk_animatedImageData]];
[strongSelf _locked_setAnimatedImage:animatedImage];
} else {
[strongSelf _locked__setImage:[imageContainer asdk_image]];
as_log_verbose(ASImageLoadingLog(), "Downloaded image for %@ img: %@ urls: %@", self, [imageContainer asdk_image], URLs);

// Grab the lock for the rest of the block
ASDN::MutexLocker l(strongSelf->__instanceLock__);

//Getting a result back for a different download identifier, download must not have been successfully canceled
if (ASObjectIsEqual(strongSelf->_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) {
return;
}
strongSelf->_imageLoaded = YES;
}

strongSelf->_downloadIdentifier = nil;
strongSelf->_cacheUUID = nil;

if (imageContainer != nil) {
if (strongSelf->_delegateFlags.delegateDidLoadImage) {
ASDN::MutexUnlocker u(strongSelf->__instanceLock__);
[delegate imageNode:strongSelf didLoadImage:strongSelf.image];

//No longer in preload range, no point in setting the results (they won't be cleared in exit preload range)
if (ASInterfaceStateIncludesPreload(self->_interfaceState) == NO) {
return;
}
} else if (error && strongSelf->_delegateFlags.delegateDidFailWithError) {
ASDN::MutexUnlocker u(strongSelf->__instanceLock__);
[delegate imageNode:strongSelf didFailWithError:error];
}

if (imageContainer != nil) {
[strongSelf _locked_setCurrentImageQuality:1.0];
if ([imageContainer asdk_animatedImageData] && strongSelf->_downloaderFlags.downloaderImplementsAnimatedImage) {
id animatedImage = [strongSelf->_downloader animatedImageWithData:[imageContainer asdk_animatedImageData]];
[strongSelf _locked_setAnimatedImage:animatedImage];
} else {
[strongSelf _locked__setImage:[imageContainer asdk_image]];
}
strongSelf->_imageLoaded = YES;
}

strongSelf->_downloadIdentifier = nil;
strongSelf->_cacheUUID = nil;

ASPerformBlockOnMainThread(^{
__typeof__(self) strongSelf = weakSelf;
if (strongSelf == nil) {
return;
}

// Grab the lock for the rest of the block
ASDN::MutexLocker l(strongSelf->__instanceLock__);

if (imageContainer != nil) {
if (strongSelf->_delegateFlags.delegateDidLoadImage) {
ASDN::MutexUnlocker u(strongSelf->__instanceLock__);
[delegate imageNode:strongSelf didLoadImage:strongSelf.image];
}
} else if (error && strongSelf->_delegateFlags.delegateDidFailWithError) {
ASDN::MutexUnlocker u(strongSelf->__instanceLock__);
[delegate imageNode:strongSelf didFailWithError:error];
}
});
});
};

// As the _cache and _downloader is only set once in the intializer we don't have to use a
Expand Down

0 comments on commit 7040a11

Please sign in to comment.