1

I want call multiple times per second the method of image but I have a memory leak.

code screenshot

I tried to do CFRelease(rawImageRef); but returns the next error:

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

Update with code:

- (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;

}
mhergon
  • 1,688
  • 1
  • 18
  • 39
  • 1
    please also post your code as code, not as image. Though keep image as well if you think it's irreplaceable. – Bruno Gelb Apr 29 '14 at 19:01
  • 3
    You should be using [`CGImageRelease`](https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGImage/Reference/reference.html#//apple_ref/doc/uid/TP30000956-CH1g-F17181), saves you checking for `NULL`. – Rich Apr 29 '14 at 19:07
  • Rich, I get the same error with CFRelease and CGImageRelease – mhergon Apr 29 '14 at 19:35
  • @mhergon how do you call this code, what is `_imageRaster`? I've just run it with a `-[UIImage CGImage]` and a `{0, 0, 100, 100}` `CGRect` and it was fine - I did add the `CGImageRelease` to fix the static analyser though. – Rich Apr 29 '14 at 19:39

3 Answers3

0

You never release rawImageRef.

I'd call CGImageRelease(rawImageRef); right after releasing data.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
0

Yes, the static analyzer is correct, that you need CGImageRelease(rawImageRef) within this method.

Your error, though, is reporting the over-release of some object. On the basis of the code snippet provided, I don't think the rawImageRef is the object in question.

Now, I don't know what you're doing with the returned CGColorRef object, but let's say you had something like the following:

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

If you have zombies turned on, that produces the error you describe:

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

This is because the colorRef object that you're returning is linked to an autorelease UIColor object, and therefore, when the pool is drained, the CGColorRef object will be released unless you did an explicit CGColorRetain. In this case, this error will go away if you remove the unnecessary CGColorRelease.

I'm not suggesting that this is precisely what you've done, but it's an illustration of the sort of thing that can generate the error you report. Perhaps you can share your code that uses the resulting CGColorRef and we can see if there's anything there that would manifest the error you shared with us. It's not clear why the introduction of the CGImageRelease(rawImageRef) would cause this error to appear whereas its not produced in the absence of that CGImageRelease. But the CGImageRelease(rawImageRef) is not the root of the problem, but rather the issue undoubtedly rests elsewhere.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thanks, but I tried this: // Add new layers CALayer *layerA = [CALayer layer]; layerA.frame = rectA; CGColorRef colorA = [self averageColorRect:rectA]; layerA.backgroundColor = colorA; [self.layer addSublayer:layerA]; CGColorRelease(colorA); But crash too! – mhergon Apr 29 '14 at 22:53
  • @mhergon No, you misunderstand my point: You definitely do _not_ want to do `CGColorRelease`, since it's not a +1 object. But is this code (short of the `CGColorRelease`, which you presumably added for my benefit) all you're doing with the resulting `CGColorRef` object? You're not saving the `CGColorRef` in a property anywhere or releasing it anywhere? There's a mismatched release somewhere, but I just don't think it's the `CGImageRelease(rawImageRef)`. – Rob Apr 29 '14 at 23:09
0

Solved! I added _imageRaster.CGIMage and after release it!! Thanks!

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

// ......

CGImageRelease(rawImageRef);
mhergon
  • 1,688
  • 1
  • 18
  • 39