我使用此功能来了解我的图片是否包含某种颜色的像素:
- (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所以我不需要释放我的“数据”数组吗?
答案 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);