Add autoreleasepool to release autorelease objects in advance when using GCD

This commit is contained in:
zhongwuzw 2018-09-07 10:48:38 +08:00
parent f22a69891c
commit 703631d51a
2 changed files with 36 additions and 28 deletions

View File

@ -361,11 +361,13 @@ didReceiveResponse:(NSURLResponse *)response
// progressive decode the image in coder queue // progressive decode the image in coder queue
dispatch_async(self.coderQueue, ^{ dispatch_async(self.coderQueue, ^{
UIImage *image = SDImageLoaderDecodeProgressiveImageData(imageData, self.request.URL, finished, self, [[self class] imageOptionsFromDownloaderOptions:self.options], self.context); @autoreleasepool {
if (image) { UIImage *image = SDImageLoaderDecodeProgressiveImageData(imageData, self.request.URL, finished, self, [[self class] imageOptionsFromDownloaderOptions:self.options], self.context);
// We do not keep the progressive decoding image even when `finished`=YES. Because they are for view rendering but not take full function from downloader options. And some coders implementation may not keep consistent between progressive decoding and normal decoding. if (image) {
// We do not keep the progressive decoding image even when `finished`=YES. Because they are for view rendering but not take full function from downloader options. And some coders implementation may not keep consistent between progressive decoding and normal decoding.
[self callCompletionBlocksWithImage:image imageData:nil error:nil finished:NO];
[self callCompletionBlocksWithImage:image imageData:nil error:nil finished:NO];
}
} }
}); });
} }
@ -428,14 +430,16 @@ didReceiveResponse:(NSURLResponse *)response
} else { } else {
// decode the image in coder queue // decode the image in coder queue
dispatch_async(self.coderQueue, ^{ dispatch_async(self.coderQueue, ^{
UIImage *image = SDImageLoaderDecodeImageData(imageData, self.request.URL, [[self class] imageOptionsFromDownloaderOptions:self.options], self.context); @autoreleasepool {
CGSize imageSize = image.size; UIImage *image = SDImageLoaderDecodeImageData(imageData, self.request.URL, [[self class] imageOptionsFromDownloaderOptions:self.options], self.context);
if (imageSize.width == 0 || imageSize.height == 0) { CGSize imageSize = image.size;
[self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorBadImageData userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}]]; if (imageSize.width == 0 || imageSize.height == 0) {
} else { [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorBadImageData userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}]];
[self callCompletionBlocksWithImage:image imageData:imageData error:nil finished:YES]; } else {
[self callCompletionBlocksWithImage:image imageData:imageData error:nil finished:YES];
}
[self done];
} }
[self done];
}); });
} }
} else { } else {

View File

@ -282,29 +282,33 @@ static id<SDImageLoader> _defaultImageLoader;
id<SDWebImageCacheSerializer> cacheSerializer = context[SDWebImageContextCacheSerializer]; id<SDWebImageCacheSerializer> cacheSerializer = context[SDWebImageContextCacheSerializer];
if (downloadedImage && (!downloadedImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage)) && transformer) { if (downloadedImage && (!downloadedImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage)) && transformer) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
UIImage *transformedImage = [transformer transformedImageWithImage:downloadedImage forKey:key]; @autoreleasepool {
if (transformedImage && finished) { UIImage *transformedImage = [transformer transformedImageWithImage:downloadedImage forKey:key];
NSString *transformerKey = [transformer transformerKey]; if (transformedImage && finished) {
NSString *cacheKey = SDTransformedKeyForKey(key, transformerKey); NSString *transformerKey = [transformer transformerKey];
BOOL imageWasTransformed = ![transformedImage isEqual:downloadedImage]; NSString *cacheKey = SDTransformedKeyForKey(key, transformerKey);
NSData *cacheData; BOOL imageWasTransformed = ![transformedImage isEqual:downloadedImage];
// pass nil if the image was transformed, so we can recalculate the data from the image NSData *cacheData;
if (cacheSerializer) { // pass nil if the image was transformed, so we can recalculate the data from the image
cacheData = [cacheSerializer cacheDataWithImage:transformedImage originalData:(imageWasTransformed ? nil : downloadedData) imageURL:url]; if (cacheSerializer) {
} else { cacheData = [cacheSerializer cacheDataWithImage:transformedImage originalData:(imageWasTransformed ? nil : downloadedData) imageURL:url];
cacheData = (imageWasTransformed ? nil : downloadedData); } else {
cacheData = (imageWasTransformed ? nil : downloadedData);
}
[self.imageCache storeImage:transformedImage imageData:cacheData forKey:cacheKey cacheType:storeCacheType completion:nil];
} }
[self.imageCache storeImage:transformedImage imageData:cacheData forKey:cacheKey cacheType:storeCacheType completion:nil];
[self callCompletionBlockForOperation:strongOperation completion:completedBlock image:transformedImage data:downloadedData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url];
} }
[self callCompletionBlockForOperation:strongOperation completion:completedBlock image:transformedImage data:downloadedData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url];
}); });
} else { } else {
if (downloadedImage && finished) { if (downloadedImage && finished) {
if (cacheSerializer) { if (cacheSerializer) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSData *cacheData = [cacheSerializer cacheDataWithImage:downloadedImage originalData:downloadedData imageURL:url]; @autoreleasepool {
[self.imageCache storeImage:downloadedImage imageData:cacheData forKey:key cacheType:storeCacheType completion:nil]; NSData *cacheData = [cacheSerializer cacheDataWithImage:downloadedImage originalData:downloadedData imageURL:url];
[self.imageCache storeImage:downloadedImage imageData:cacheData forKey:key cacheType:storeCacheType completion:nil];
}
}); });
} else { } else {
[self.imageCache storeImage:downloadedImage imageData:downloadedData forKey:key cacheType:storeCacheType completion:nil]; [self.imageCache storeImage:downloadedImage imageData:downloadedData forKey:key cacheType:storeCacheType completion:nil];