修复警告“在此块中强烈捕获[对象]可能会导致保留周期”在启用 ARC 的代码中
在启用 ARC 的代码中,使用基于块的 API 时如何修复有关潜在保留周期的警告?
警告:在此块中强烈捕获“请求”可能会导致
此代码片段产生的保留周期:
ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:...
[request setCompletionBlock:^{
NSDictionary *jsonDictionary = [[CJSONDeserializer deserializer] deserialize:request.rawResponseData error:nil];
// ...
}];
警告与块内对象request
的使用相关联。
In ARC enabled code, how to fix a warning about a potential retain cycle, when using a block-based API?
The warning:Capturing 'request' strongly in this block is likely to lead to a retain cycle
produced by this snippet of code:
ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:...
[request setCompletionBlock:^{
NSDictionary *jsonDictionary = [[CJSONDeserializer deserializer] deserialize:request.rawResponseData error:nil];
// ...
}];
Warning is linked to the use of the object request
inside the block.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
回复我自己:
我对文档的理解是,使用关键字
block
并在块内使用它后将变量设置为 nil 应该没问题,但它仍然显示警告。更新:让它使用关键字“_weak”而不是“_block”,并使用临时变量:
如果您还想面向 iOS 4,请使用 <代码>__unsafe_unretained而不是
__weak
。行为相同,但当对象被销毁时,指针保持悬空状态,而不是自动设置为 nil。Replying to myself:
My understanding of the documentation says that using keyword
block
and setting the variable to nil after using it inside the block should be ok, but it still shows the warning.Update: got it to work with the keyword '_weak' instead of '_block', and using a temporary variable:
If you want to also target iOS 4, use
__unsafe_unretained
instead of__weak
. Same behavior, but the pointer stays dangling instead of being automatically set to nil when the object is destroyed.出现此问题的原因是您为请求分配了一个块,该块对其中的请求具有强引用。该块会自动保留请求,因此原始请求不会因为循环而释放。有道理吗?
这很奇怪,因为您使用 __block 标记请求对象,以便它可以引用自身。您可以通过在其旁边创建一个弱引用来解决此问题。
The issue occurs because you're assigning a block to request that has a strong reference to request in it. The block will automatically retain request, so the original request won't deallocate because of the cycle. Make sense?
It's just weird because you're tagging the request object with __block so it can refer to itself. You can fix this by creating a weak reference alongside it.
这是由于将自我保留在块中而引起的。 Block将从self访问,并且self在block中被引用。这将创建一个保留周期。
尝试通过创建
self
的弱引用来解决此问题It causes due to retaining the self in the block. Block will accessed from self, and self is referred in block. this will create a retain cycle.
Try solving this by create a weak refernce of
self
有时,xcode 编译器在识别保留周期方面存在问题,因此,如果您确定没有保留完成块,您可以放置一个编译器标志,如下所示:
Some times the xcode compiler has problems for identifier the retain cycles, so if you are sure that you isn't retain the completionBlock you can put a compiler flag like this:
当我尝试 Guillaume 提供的解决方案时,在调试模式下一切正常,但在发布模式下崩溃。
请注意,不要使用 __weak 而是 __unsafe_unretained,因为我的目标是 iOS 4.3。
当对对象“request”调用 setCompletionBlock: 时,我的代码崩溃:请求被释放...
因此,此解决方案在调试和发布模式下都有效:
When I try the solution provided by Guillaume, everything is fine in Debug mode but it crashs in Release mode.
Note that don't use __weak but __unsafe_unretained because my target is iOS 4.3.
My code crashs when setCompletionBlock: is called on object "request" : request was deallocated ...
So, this solution works both in Debug and Release modes :
__weak 和 __block 引用之间有什么区别?
what the difference between __weak and __block reference?
查看 Apple 开发者网站上的文档: https://developer.apple.com/library/prerelease/ios/#documentation/General/Conceptual/ARCProgrammingGuide/Introduction.html#//apple_ref/doc/uid/TP40011029
有页面底部有关保留循环的部分。
Take a look at the documentation on the Apple developer website : https://developer.apple.com/library/prerelease/ios/#documentation/General/Conceptual/ARCProgrammingGuide/Introduction.html#//apple_ref/doc/uid/TP40011029
There is a section about retain cycles at the bottom of the page.