为什么SDWebImage在decodeImageWithImage方法中使用@autoreleasepool块?

问题描述 投票:0回答:1

看起来像下面的代码片段,它在此方法中使用@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也将占据记忆。

任何人都可以解释一下,谢谢!

ios memory-management sdwebimage autorelease
1个回答
0
投票

通过这个apple doc。有人提到

有三次你可能会使用自己的自动释放池块:

  • 如果您正在编写不基于UI框架的程序,例如命令行工具。
  • 如果编写一个创建许多临时对象的循环。您可以在循环内使用自动释放池块在下一次迭代之前处理这些对象。在循环中使用自动释放池块有助于减少应用程序的最大内存占用量。
  • 如果你产生一个辅助线程。一旦线程开始执行,您必须创建自己的自动释放池块;否则,您的应用程序将泄漏对象。 (有关详细信息,请参阅自动释放池块和线程。)

我不确定第一点,但SDWebImage肯定会使用autoreleasepool其他两点。

© www.soinside.com 2019 - 2024. All rights reserved.