为什么 CG Image 没有发布?

Why is CG Image not being released?

一段时间以来,我一直在为一个内存泄漏的大型项目苦思冥想。我已经设法创建了一个非常基本的 CLI 应用程序来重现这个问题。

为什么CG图没有发布?

真正的应用程序实际上会创建一堆大小不一的拇指。这只是演示只是一遍又一遍地使用相同的大小。

这是在没有 ARC 的情况下编译的。

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        NSString * image = @"/Users/sean/Pictures/wallpaper/7gjMT.jpg";
        NSData * imageData = [NSData dataWithContentsOfFile:image];

        CFDataRef imgData = (CFDataRef)imageData;
        CGImageRef imgRef;
        CGDataProviderRef imgDataProvider = NULL;
        imgDataProvider = CGDataProviderCreateWithCFData(imgData);
        imgRef = CGImageCreateWithJPEGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault);
        CGDataProviderRelease(imgDataProvider);

        for (int i = 0; i < 50; i++) {
            // create context, keeping original image properties
            CGColorSpaceRef colorspace = CGImageGetColorSpace(imgRef);

            CGContextRef context = CGBitmapContextCreate(NULL, 2560, 1440,
                                            CGImageGetBitsPerComponent(imgRef),
                                            CGImageGetBytesPerRow(imgRef),
                                            colorspace,
                                            kCGImageAlphaPremultipliedFirst);

            CGColorSpaceRelease(colorspace);

            // draw image to context (resizing it)
            CGContextDrawImage(context, CGRectMake(0, 0, 2560, 1440), imgRef);

            // extract resulting image from context
            CGImageRef newImgRef = CGBitmapContextCreateImage(context);

            CGImageRelease(imgRef);
            imgRef = newImgRef;
        }
    }
    return 0;
}
  1. 上下文永远不会被释放。将 CGContextRelease(context); 添加到您的 for 循环
  2. 您可能想将 for 循环中的内容添加到 @autoreleaspool{}
for (int i = 0; i < 50; i++) {

  @autoreleaspool { 
        CGColorSpaceRef colorspace = CGImageGetColorSpace(imgRef);

        CGContextRef context = CGBitmapContextCreate(NULL, 2560, 1440,
                                        CGImageGetBitsPerComponent(imgRef),
                                        CGImageGetBytesPerRow(imgRef),
                                        colorspace,
                                        kCGImageAlphaPremultipliedFirst);

        CGColorSpaceRelease(colorspace);

        // draw image to context (resizing it)
        CGContextDrawImage(context, CGRectMake(0, 0, 2560, 1440), imgRef);

        // extract resulting image from context
        CGImageRef newImgRef = CGBitmapContextCreateImage(context);

        CGImageRelease(imgRef);
        CGContextRelease(context);

        imgRef = newImgRef;
    }
}