为什么SDWebImage在decodeImageWithImage方法中使用@autoreleasepool块?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么SDWebImage在decodeImageWithImage方法中使用@autoreleasepool块?相关的知识,希望对你有一定的参考价值。
看起来像下面的代码片段,它在此方法中使用@autoreleasepool
块。
+ (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;
}
}
(该方法在SDWebImageDecoder.m中,版本为SDWebImage 3.7.0)。
我很困惑,因为这些temp objects
将在方法返回后被释放,所以是否有必要使用autoreleasepool
才能在之前释放它们? autoreleasepool
也将占据记忆。
任何人都可以解释一下,谢谢!
答案
通过这个apple doc。有人提到
有三次你可能会使用自己的自动释放池块:
- 如果您正在编写不基于UI框架的程序,例如命令行工具。
- 如果编写一个创建许多临时对象的循环。您可以在循环内使用自动释放池块在下一次迭代之前处理这些对象。在循环中使用自动释放池块有助于减少应用程序的最大内存占用量。
- 如果你产生一个辅助线程。一旦线程开始执行,您必须创建自己的自动释放池块;否则,您的应用程序将泄漏对象。 (有关详细信息,请参阅自动释放池块和线程。)
我不确定第一点,但SDWebImage
肯定会使用autoreleasepool
其他两点。
以上是关于为什么SDWebImage在decodeImageWithImage方法中使用@autoreleasepool块?的主要内容,如果未能解决你的问题,请参考以下文章
iOS开发中SDWebImage加载图片不显示(图片地址在浏览器中能显示)
为啥所有异步图像加载(SDWebImage、AFNetworking)库都使用 UIImageView 而不是 UIImage?
ASIHttpRequest或者SDWebImage给UIImageView加载图片的逻辑是什么样子的