Ensure every data manipulation performed in NSURLConnection delegates are handled in the global background queue
This commit is contained in:
parent
bf1b946b9a
commit
b5bb74bf96
|
@ -162,95 +162,97 @@
|
|||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
|
||||
{
|
||||
[self.imageData appendData:data];
|
||||
|
||||
if ((self.options & SDWebImageDownloaderProgressiveDownload) && self.expectedSize > 0 && self.completedBlock)
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
|
||||
{
|
||||
// The following code is from http://www.cocoaintheshell.com/2011/05/progressive-images-download-imageio/
|
||||
// Thanks to the author @Nyx0uf
|
||||
[self.imageData appendData:data];
|
||||
|
||||
// Get the total bytes downloaded
|
||||
const NSUInteger totalSize = self.imageData.length;
|
||||
|
||||
// Update the data source, we must pass ALL the data, not just the new bytes
|
||||
CGImageSourceRef imageSource = CGImageSourceCreateIncremental(NULL);
|
||||
CGImageSourceUpdateData(imageSource, (__bridge CFDataRef)self.imageData, totalSize == self.expectedSize);
|
||||
|
||||
if (width + height == 0)
|
||||
if ((self.options & SDWebImageDownloaderProgressiveDownload) && self.expectedSize > 0 && self.completedBlock)
|
||||
{
|
||||
CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL);
|
||||
if (properties)
|
||||
// The following code is from http://www.cocoaintheshell.com/2011/05/progressive-images-download-imageio/
|
||||
// Thanks to the author @Nyx0uf
|
||||
|
||||
// Get the total bytes downloaded
|
||||
const NSUInteger totalSize = self.imageData.length;
|
||||
|
||||
// Update the data source, we must pass ALL the data, not just the new bytes
|
||||
CGImageSourceRef imageSource = CGImageSourceCreateIncremental(NULL);
|
||||
CGImageSourceUpdateData(imageSource, (__bridge CFDataRef)self.imageData, totalSize == self.expectedSize);
|
||||
|
||||
if (width + height == 0)
|
||||
{
|
||||
CFTypeRef val = CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight);
|
||||
if (val) CFNumberGetValue(val, kCFNumberLongType, &height);
|
||||
val = CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth);
|
||||
if (val) CFNumberGetValue(val, kCFNumberLongType, &width);
|
||||
CFRelease(properties);
|
||||
CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL);
|
||||
if (properties)
|
||||
{
|
||||
CFTypeRef val = CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight);
|
||||
if (val) CFNumberGetValue(val, kCFNumberLongType, &height);
|
||||
val = CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth);
|
||||
if (val) CFNumberGetValue(val, kCFNumberLongType, &width);
|
||||
CFRelease(properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (width + height > 0 && totalSize < self.expectedSize)
|
||||
{
|
||||
// Create the image
|
||||
CGImageRef partialImageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
|
||||
if (width + height > 0 && totalSize < self.expectedSize)
|
||||
{
|
||||
// Create the image
|
||||
CGImageRef partialImageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
|
||||
|
||||
#ifdef TARGET_OS_IPHONE
|
||||
// Workaround for iOS anamorphic image
|
||||
if (partialImageRef)
|
||||
{
|
||||
const size_t partialHeight = CGImageGetHeight(partialImageRef);
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
CGContextRef bmContext = CGBitmapContextCreate(NULL, width, height, 8, width * 4, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
if (bmContext)
|
||||
// Workaround for iOS anamorphic image
|
||||
if (partialImageRef)
|
||||
{
|
||||
CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = partialHeight}, partialImageRef);
|
||||
CGImageRelease(partialImageRef);
|
||||
partialImageRef = CGBitmapContextCreateImage(bmContext);
|
||||
CGContextRelease(bmContext);
|
||||
const size_t partialHeight = CGImageGetHeight(partialImageRef);
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
CGContextRef bmContext = CGBitmapContextCreate(NULL, width, height, 8, width * 4, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
if (bmContext)
|
||||
{
|
||||
CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = partialHeight}, partialImageRef);
|
||||
CGImageRelease(partialImageRef);
|
||||
partialImageRef = CGBitmapContextCreateImage(bmContext);
|
||||
CGContextRelease(bmContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGImageRelease(partialImageRef);
|
||||
partialImageRef = nil;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CGImageRelease(partialImageRef);
|
||||
partialImageRef = nil;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (partialImageRef)
|
||||
{
|
||||
UIImage *image = [UIImage decodedImageWithImage:SDScaledImageForPath(self.request.URL.absoluteString, [UIImage imageWithCGImage:partialImageRef])];
|
||||
CGImageRelease(partialImageRef);
|
||||
self.completedBlock(image, nil, NO);
|
||||
if (partialImageRef)
|
||||
{
|
||||
UIImage *image = [UIImage decodedImageWithImage:SDScaledImageForPath(self.request.URL.absoluteString, [UIImage imageWithCGImage:partialImageRef])];
|
||||
CGImageRelease(partialImageRef);
|
||||
self.completedBlock(image, nil, NO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(imageSource);
|
||||
}
|
||||
CFRelease(imageSource);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection *)aConnection
|
||||
{
|
||||
self.connection = nil;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil];
|
||||
|
||||
if (self.completedBlock)
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
|
||||
{
|
||||
__block SDWebImageDownloaderCompletedBlock completionBlock = self.completedBlock;
|
||||
UIImage *image = SDScaledImageForPath(self.request.URL.absoluteString, self.imageData);
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil];
|
||||
|
||||
if (self.completedBlock)
|
||||
{
|
||||
UIImage *decodedImage = [UIImage decodedImageWithImage:image];
|
||||
__block SDWebImageDownloaderCompletedBlock completionBlock = self.completedBlock;
|
||||
UIImage *image = [UIImage decodedImageWithImage:SDScaledImageForPath(self.request.URL.absoluteString, self.imageData)];
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
completionBlock(decodedImage, nil, YES);
|
||||
completionBlock(image, nil, YES);
|
||||
completionBlock = nil;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[self done];
|
||||
[self done];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
|
||||
|
|
Loading…
Reference in New Issue