在ARC下容器中处理CGImageRef的正确方法

时间:2013-12-11 21:33:14

标签: ios objective-c automatic-ref-counting cgimageref toll-free-bridging

我很想在我的项目中加入arc。我正在尝试理解__bridge及其小朋友,以便在从容器中添加和删除它时可以正确地投射我的CGImageRef。

我的一条线路上出现了“存储物体的潜在泄漏......”。这是我的代码的基本周期:

CGImageRef renderedRef = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext());
[_array addObject: (__bridge_transfer id)renderedRef];//_array is an iVar

然后在某个地方,我这样做:

    CGImageRef iRef = (__bridge_retained CGImageRef)array[0];
//then I do something fancy with iRef
//at the end of the method, I get "Potential leak of an object stored…"
//I have no idea what to do
//I've tried CGImageRelease(iRef); but it still doesn't change the warning. 

有人可以对此有所了解吗?另外,我尝试过只使用__bridge,但这并没有什么区别。

修改1:

我扩展了分析仪结果并跟踪发生的情况。这是因为我在这样的方法中使用iRef:[self doSomethingFancy:iRef];在那种方法中,iRef被保留但未被释放。这样就修复了警告,但我仍然有些困惑。

我不太清楚何时使用各种__bridge演员表。在ARC下,以下是否会增加引用计数?

CGImageRef iRef = (__bridge CGImageRef)array[0];

此外,在某些时候,如果我告诉我的_array iVar删除AllObjects,是否会减少他们的引用计数?

1 个答案:

答案 0 :(得分:6)

// This WILL NOT increment the image's retain count.
CGImageRef iRef = (__bridge CGImageRef)array[0];

// This WILL increment the image's retain count.
CGImageRef iRef = (__bridge_retained CGImageRef)array[0];

由于__bridge_retained增加了保留计数,因此需要在稍后的某个时间点减少保留计数。由于__bridge_retained的作用类似CFRetain,因此Apple创建了一个名为__bridge_retained的{​​{1}}包装器,提醒您:

CFBridgingRetain

每当您看到// This WILL increment the image's retain count. CGImageRef iRef = CFBridgingRetain(array[0]); CFRetain时,您就知道您需要稍后释放该对象。

同样,您可以使用CFBridgingRetain而不是CFBridgingRelease来减少CF对象的保留计数。例如:

__bridge_transfer

您可以使用[_array addObject:CFBridgingRelease(renderedRef)]; 来平衡CFBridgingReleaseCFRetain。它返回ARC管理的CFBridgingRetain

普通id保留其每个元素。你可以告诉它变空:

NSMutableArray

执行此操作时,它将释放每个元素,平衡对每个元素执行的保留。

因此,此代码中没有内存泄漏:

[_array removeAllObjects];

或在此代码中:

CGImageRef image = CGImageCreate(...);
[_array addObject:CFBridgingRelease(image)];
[_array removeAllObjects];