释放CGImageRef以避免内存泄漏

时间:2014-04-29 18:53:08

标签: ios objective-c memory-leaks crash cgimageref

我希望每秒多次调用图像方法但我有内存泄漏。

code screenshot

我尝试CFRelease(rawImageRef);但返回下一个错误:

-[Not A Type retain]: message sent to deallocated instance 0x14dd3770

使用代码更新:

- (CGColorRef)averageColorRect:(CGRect)rect {

    CGImageRef rawImageRef = CGImageCreateWithImageInRect(_imageRaster, rect);

    // This function returns the raw pixel values
    CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(rawImageRef));
    const UInt8 *rawPixelData = CFDataGetBytePtr(data);

    NSUInteger imageHeight = CGImageGetHeight(rawImageRef);
    NSUInteger imageWidth  = CGImageGetWidth(rawImageRef);
    NSUInteger bytesPerRow = CGImageGetBytesPerRow(rawImageRef);
    NSUInteger stride = CGImageGetBitsPerPixel(rawImageRef) / 8;

    // Here I sort the R,G,B, values and get the average over the whole image
    unsigned int red   = 0;
    unsigned int green = 0;
    unsigned int blue  = 0;

    for (int row = 0; row < imageHeight; row++) {
        const UInt8 *rowPtr = rawPixelData + bytesPerRow * row;
        for (int column = 0; column < imageWidth; column++) {
            red    += rowPtr[0];
            green  += rowPtr[1];
            blue   += rowPtr[2];
            rowPtr += stride;

        }
    }
    CFRelease(data);

    CGFloat f = 1.0f / (255.0f * imageWidth * imageHeight);
    return [UIColor colorWithRed:f * red  green:f * green blue:f * blue alpha:1].CGColor;

}

3 个答案:

答案 0 :(得分:0)

您永远不会发布rawImageRef

我在发布CGImageRelease(rawImageRef);后立即致电data

答案 1 :(得分:0)

是的,静态分析器是正确的,您需要在此方法中使用CGImageRelease(rawImageRef)

但是,您的错误是报告某个对象的过度释放。根据提供的代码段,我不认为rawImageRef是相关对象。

现在,我不知道你对返回的CGColorRef对象做了什么,但是让我们说你有以下内容:

CGColor colorRef = [self averageColorRect:CGRectMake(0, 0, 20, 20)];

// do something with `colorRef`

// now, all done, clean up

CGColorRelease(colorRef);        // error; you don't want this line

如果您打开了僵尸,则会产生您描述的错误:

-[Not A Type release]: message sent to deallocated instance 0x8de4e90

这是因为您返回的colorRef对象链接到自动释放UIColor对象,因此,当池耗尽时,CGColorRef对象将是除非你做了明确的CGColorRetain,否则会被释放。在这种情况下,如果您删除不必要的CGColorRelease

,则此错误将消失

我并不是说这正是您所做的,而是说明了可以产生您报告错误的事情。也许您可以分享使用结果CGColorRef的代码,我们可以查看是否有任何内容可以显示您与我们分享的错误。不清楚为什么引入CGImageRelease(rawImageRef)会导致出现此错误,而在没有CGImageRelease的情况下不会产生错误。但CGImageRelease(rawImageRef)不是问题的根源,而是问题无疑在其他地方。

答案 2 :(得分:0)

解决! 我添加了_imageRaster。 CGIMage 并在发布后!! 谢谢!

CGImageRef rawImageRef = CGImageCreateWithImageInRect(_imageRaster.CGImage, rect);

// ......

CGImageRelease(rawImageRef);