与CGDataProviderCopyData相关的内存泄漏

时间:2013-09-22 08:56:08

标签: ios memory-leaks core-graphics ios7

我使用此功能来了解我的图片是否包含某种颜色的像素:


     - (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所以我不需要释放我的“数据”数组吗?

3 个答案:

答案 0 :(得分:5)

CGDataProviderCopyData返回所有权,就像其名称所示:复制功能属于so documented

所以,你拥有那个数据对象。

ARC默认不管理CF对象,并且__bridge强制转换不会更改ARC对象的内存管理:它不会导致ARC保留对象也不会释放它。

因此,由于您使用了__bridge,您仍有义务发布数据。

选项1是通过调用CFRelease((__bridge CFDataRef)data)来维护您的义务并自行发布数据。

选项2是告诉ARC“这里,当我完成它时处理它”。为此,您需要使用__bridge_transfer强制转换将对象的管理转移到ARC。

只选择其中一个选项。如果您将对象的管理转移到ARC,自行释放 - 转移意味着您不再需要去做;你已将责任转移到ARC。


虽然我们讨论的是发布内容:您不需要也不应该发布imageRef UIImage拥有该内容但您没有。如果你从拥有它的UIImage下面发布它,你将导致崩溃。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

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

//.. do some stuff 

//Releaase data 

CFRelease(theData);