Look like the code snippet below, it use the @autoreleasepool
block in this method.
+ (UIImage *)decodedImageWithImage:(UIImage *)image {
// while downloading huge amount of images
// autorelease the bitmap context
// and all vars to help system to free memory
// when there are memory warning.
// on iOS7, do not forget to call
// [[SDImageCache sharedImageCache] clearMemory];
if (image == nil) { // Prevent "CGBitmapContextCreateImage: invalid context 0x0" error
return nil;
}
@autoreleasepool{
// do not decode animated images
if (image.images != nil) {
return image;
}
CGImageRef imageRef = image.CGImage;
CGImageAlphaInfo alpha = CGImageGetAlphaInfo(imageRef);
BOOL anyAlpha = (alpha == kCGImageAlphaFirst ||
alpha == kCGImageAlphaLast ||
alpha == kCGImageAlphaPremultipliedFirst ||
alpha == kCGImageAlphaPremultipliedLast);
if (anyAlpha) {
return image;
}
// current
CGColorSpaceModel imageColorSpaceModel = CGColorSpaceGetModel(CGImageGetColorSpace(imageRef));
CGColorSpaceRef colorspaceRef = CGImageGetColorSpace(imageRef);
BOOL unsupportedColorSpace = (imageColorSpaceModel == kCGColorSpaceModelUnknown ||
imageColorSpaceModel == kCGColorSpaceModelMonochrome ||
imageColorSpaceModel == kCGColorSpaceModelCMYK ||
imageColorSpaceModel == kCGColorSpaceModelIndexed);
if (unsupportedColorSpace) {
colorspaceRef = CGColorSpaceCreateDeviceRGB();
}
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
// kCGImageAlphaNone is not supported in CGBitmapContextCreate.
// Since the original image here has no alpha info, use kCGImageAlphaNoneSkipLast
// to create bitmap graphics contexts without alpha info.
CGContextRef context = CGBitmapContextCreate(NULL,
width,
height,
bitsPerComponent,
bytesPerRow,
colorspaceRef,
kCGBitmapByteOrderDefault|kCGImageAlphaNoneSkipLast);
// Draw the image into the context and retrieve the new bitmap image without alpha
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGImageRef imageRefWithoutAlpha = CGBitmapContextCreateImage(context);
UIImage *imageWithoutAlpha = [UIImage imageWithCGImage:imageRefWithoutAlpha
scale:image.scale
orientation:image.imageOrientation];
if (unsupportedColorSpace) {
CGColorSpaceRelease(colorspaceRef);
}
CGContextRelease(context);
CGImageRelease(imageRefWithoutAlpha);
return imageWithoutAlpha;
}
}
(the method is in SDWebImageDecoder.m, the version is SDWebImage 3.7.0).
I am confused with it, because these temp objects
will be released after the method return, so is it necessary to use the autoreleasepool
to release them only a little before? the autoreleasepool
will also occupy the memory.
anyone can explain it, thanks!
Go through this apple doc. It is mentioned that
Three occasions when you might use your own autorelease pool blocks:
If you are writing a program that is not based on a UI framework, such as a command-line tool.
If you write a loop that creates many temporary objects. You may use an autorelease pool block inside the loop to dispose of those objects before the next iteration. Using an autorelease pool block in the loop helps to reduce the maximum memory footprint of the application.
If you spawn a secondary thread. You must create your own autorelease pool block as soon as the thread begins executing; otherwise, your application will leak objects. (See Autorelease Pool Blocks and Threads for details.)
I am not sure about the first point, but SDWebImage
will surely use autoreleasepool
for other two points.