我很想在我的项目中加入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,是否会减少他们的引用计数?
答案 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)];
来平衡CFBridgingRelease
或CFRetain
。它返回ARC管理的CFBridgingRetain
。
普通id
保留其每个元素。你可以告诉它变空:
NSMutableArray
执行此操作时,它将释放每个元素,平衡对每个元素执行的保留。
因此,此代码中没有内存泄漏:
[_array removeAllObjects];
或在此代码中:
CGImageRef image = CGImageCreate(...);
[_array addObject:CFBridgingRelease(image)];
[_array removeAllObjects];