CoreGraphics随机崩溃

时间:2015-03-07 03:13:18

标签: objective-c core-graphics

这是一个小型测试程序,用于复制较大类中的间歇性问题。真正的班级创造了4个不同大小的拇指。

这个main.m程序将在使用EXC_BAD_ACCESS运行的5次中崩溃1次,并突出显示CGImageRelease(imgRef);如果我注释掉CGImageRelease(imgRef),那么应用程序会遇到严重的内存泄漏,但不会崩溃......

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

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

    @autoreleasepool {


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

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

        for (int i = 0; i < 1000; 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;
            newImgRef = CGBitmapContextCreateImage(context);
            CGImageRelease(imgRef);
            CGContextRelease(context);

            imgRef = newImgRef;
        }



    }
    return 0;
}

我发现如果我首先释放上下文然后10个失败中的1个突出显示CGImageGetBytesPerRow(imgRef)并出现相同的错误。

我为malloc_error_break添加了一个断点,并在CGImageRelease上得到了这个:

enter image description here

CGImageRelease和CGImageRelease是否发布共享资源?

1 个答案:

答案 0 :(得分:2)

主要问题几乎可以肯定是你发布了一个你不拥有的色彩空间。 CGImageGetColorSpace(imgRef)不会为您提供返回的颜色空间对象的所有权,因此您以后不应该调用CGColorSpaceRelease(colorspace)。 (顺便说一句,虽然我碰巧遇到了一个不同的故障,但我也解决了这个问题,静态分析仪也抓住了这个。)

作为次要问题,我在创建上下文时遇到了失败,因为您使用了不合适的每行字节数值。 CGImageGetBytesPerRow(imgRef)是该图像的每行字节数,但这仅适用于该图像的宽度。鉴于您要对宽度进行硬编码而不是使用图像的宽度(因为您正在缩放),您不应该使用图像的每行字节数。

我想如果你缩小规模会有效,但会浪费空间。如果您正在扩展,则会失败。

无论如何,传递0.这使得CGBitmapContextCreate()可以计算出最佳值。