3

我是新来在我的项目中加入弧。我正在尝试了解 __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 删除所有对象,那会正确减少它们的引用计数吗?

4

1 回答 1

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名为的包装器CFBridgingRetain来提醒您:

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

每当您看到CFRetain CFBridgingRetain时,您就知道稍后需要释放该对象。

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

[_array addObject:CFBridgingRelease(renderedRef)];

您可以使用CFBridgingRelease来平衡 aCFRetain或 a CFBridgingRetain。它返回一个idARC 管理的。

法线NSMutableArray保留其每个元素。你可以告诉它变成空的:

[_array removeAllObjects];

当你这样做时,它将释放它的每个元素,平衡它对每个元素执行的保留。

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

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

或在此代码中:

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

CGImageRef image2 = CFBridgingRetain([_array lastObject]);
[_array removeLastObject];
CGContextDrawImage(gc, rect, image2);
CGImageRelease(image2);
于 2013-12-11T23:00:04.827 回答