【问题标题】:Release CGImageRef to avoid memory leak释放 CGImageRef 以避免内存泄漏
【发布时间】:2023-03-23 03:31:02
【问题描述】:

我想每秒多次调用 image 方法,但我有内存泄漏。

我尝试做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;

}

【问题讨论】:

  • 请将您的代码发布为代码,而不是图像。如果您认为它是不可替代的,请保留图像。
  • 你应该使用CGImageRelease,省去你检查NULL的时间。
  • Rich,我在使用 CFRelease 和 CGI​​mageRelease 时遇到同样的错误
  • @mhergon 你怎么称呼这段代码,_imageRaster 是什么?我刚刚使用-[UIImage CGImage]{0, 0, 100, 100} CGRect 运行它,这很好 - 我确实添加了CGImageRelease 来修复静态分析器。

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


【解决方案1】:

你永远不会释放rawImageRef

我会在释放data 后立即致电CGImageRelease(rawImageRef);

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      不过,您的错误是报告某些对象的过度释放。根据提供的代码 sn-p,我不认为 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]:消息发送到释放的实例 0x8de4e90

      这是因为您返回的 colorRef 对象链接到自动释放 UIColor 对象,因此,当池耗尽时,CGColorRef 对象将被释放,除非您执行明确的 @987654328 @。在这种情况下,如果您删除不必要的CGColorRelease,此错误就会消失。

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

      【讨论】:

      • 谢谢,但我试过了: // 添加新层 CALayer *layerA = [CALayer layer]; layerA.frame = rectA; CGColorRef colorA = [self averageColorRect:rectA]; layerA.backgroundColor = colorA; [self.layer addSublayer:layerA]; CGColorRelease(colorA);但也会崩溃!
      • @mhergon 不,你误解了我的意思:你肯定想做CGColorRelease,因为它不是+1 对象。但是这段代码(缺少CGColorRelease,您可能是为了我的利益而添加的)是您对生成的CGColorRef 对象所做的一切吗?您没有将CGColorRef 保存在任何地方的属性中或在任何地方释放它?某处有一个不匹配的版本,但我不认为是CGImageRelease(rawImageRef)
      猜你喜欢
      • 2014-08-26
      • 2010-12-04
      • 1970-01-01
      • 1970-01-01
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多