【问题标题】:Memory leak related to CGDataProviderCopyData与 CGDataProviderCopyData 相关的内存泄漏
【发布时间】:2013-09-27 07:59:21
【问题描述】:

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


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

【问题讨论】:

  • ARC 不会为您管理 Core Foundation 对象。
  • 那么我应该释放哪个对象?如何 ?因为我做不到[对象释放]
  • 我做了:CGDataProviderRef provider = CGImageGetDataProvider(imageRef);和 CFRelease(提供者);之后,但我仍然从 CGImageGetDataProvider 得到内存泄漏
  • @JeanFrançoisManatane: &amp;data 不是一个对象;它是一个变量的地址。但是,data 确实引用了一个对象。

标签: ios memory-leaks core-graphics ios7


【解决方案1】:

CGDataProviderCopyData 返回一个所有权,就像它的名字所说的那样:Copy 函数在 so documented 中。

因此,您拥有该数据对象。

默认情况下,ARC 不管理 CF 对象,__bridge 强制转换不会改变 ARC 对对象的内存管理:它不会导致 ARC 保留或释放对象。

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

选项 1 是履行您的义务并自行发布数据,请致电CFRelease((__bridge CFDataRef)data)

选项 2 是告诉 ARC“在这里,我用完后将其丢弃”。为此,您需要使用 __bridge_transfer 强制转换将对象的管理转移到 ARC。

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


虽然我们正在讨论发布内容:您不需要也不应该发布imageRef UIImage 拥有它,而您不拥有。如果从拥有它的 UIImage 下释放它会导致崩溃。

【讨论】:

    【解决方案2】:
    NSData *data = (__bridge_transfer NSData *)CGDataProviderCopyData(CGImageGetDataProvider(imageRef)); 
    

    【讨论】:

      【解决方案3】:

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

      CFDataRef theData; 
      theData = CGDataProviderCopyData(CGImageGetDataProvider(imageRef));
      NSData *data = (__bridge NSData *)theData; 
      
      //.. do some stuff 
      
      //Releaase data 
      
      CFRelease(theData);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-19
        • 1970-01-01
        • 1970-01-01
        • 2013-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多