1

我使用这个函数来知道我的图片是否包含某种颜色的像素:


     - (BOOL)imageHasOrange:(UIImage *)img
     {
           CGImageRef imageRef = img.CGImage;

    NSData *data = (__bridge NSData *)  CGDataProviderCopyData(CGImageGetDataProvider(imageRef));

           unsigned char *pixels = (unsigned char *)[data bytes];

           BOOL hasColor = NO;

           for(int i = 0; i < [data length]; i += 4)
           {
                if(pixels[i] == 255 && pixels[i+1] == 132 && pixels[i+2] == 0)
                {
                   hasColor = YES;
                   break;
                }
           }

           CFRelease(imageRef);

           return hasColor;

      }

当我使用 Instruments 跟踪内存泄漏时,它说它与 CGDataProviderCopyData 函数有关。

但我使用 ARC,所以我不需要释放我的“数据”数组,对吗?

4

3 回答 3

5

CGDataProviderCopyData returns an ownership, like its name says: Copy functions are among those so documented.

So, you own that data object.

ARC does not manage CF objects by default, and a __bridge cast does not change ARC's memory management of an object: it will not cause ARC to retain the object nor to release it.

Thus, because you used __bridge, you are still obliged to release the data.

Option 1 is to uphold your obligation and release the data yourself, by calling CFRelease((__bridge CFDataRef)data).

Option 2 is to tell ARC “here, dispose of this when I'm done with it”. To do that, you need to use a __bridge_transfer cast to transfer management of the object to ARC.

Choose only one of these options. If you transfer management of the object to ARC, don't release it yourself—the transfer means that you no longer need to do that; you've transferred that responsibility to ARC.


While we're on the subject of releasing things: You do not need to, and should not, release imageRef. The UIImage owns that and you don't. You will cause a crash if you release it out from under the UIImage that owns it.

于 2013-09-22T23:27:41.873 回答
1
NSData *data = (__bridge_transfer NSData *)CGDataProviderCopyData(CGImageGetDataProvider(imageRef)); 
于 2014-03-04T04:52:02.887 回答
0

您实际上是在释放 CGImageRef 而不是 CGDataRef 的副本 您可以做的是创建一个单独的 CGDataRef 对象,将数据复制到其中,然后在完成数据后释放它 像这样。

CFDataRef theData; 
theData = CGDataProviderCopyData(CGImageGetDataProvider(imageRef));
NSData *data = (__bridge NSData *)theData; 

//.. do some stuff 

//Releaase data 

CFRelease(theData);
于 2013-10-27T11:07:43.277 回答