如何修复警告“在该块中强烈捕获很可能导致启用ARC代码中的保留周期”?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (15)

在启用ARC的代码中,如何在使用基于块的API时修复关于潜在保留周期的警告?

警告: Capturing 'request' strongly in this block is likely to lead to a retain cycle

由这段代码产生:

ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:...

[request setCompletionBlock:^{
    NSDictionary *jsonDictionary = [[CJSONDeserializer deserializer] deserialize:request.rawResponseData error:nil];
    // ...
    }];

警告与request块内对象的使用有关。

提问于
用户回答回答于

使用关键字'_ weak'而不是' _block'并使用临时变量:

ASIHTTPRequest *_request = [[ASIHTTPRequest alloc] initWithURL:...
__weak ASIHTTPRequest *request = _request;

[request setCompletionBlock:^{
    NSDictionary *jsonDictionary = [[CJSONDeserializer deserializer] deserialize:request.responseData error:nil];
    // ...
    }];

如果你想要也瞄准iOS 4,使用,__unsafe_unretained而不是__weak。相同的行为,但指针保持悬浮状态,而不是在对象被销毁时自动设置为零。

用户回答回答于

发生该问题的原因是你正在分配一个请求,该请求中有一个强烈的请求请求。该块将自动保留请求,所以原始请求不会因循环而释放。合理?

这很奇怪,因为你用__block标记请求对象,所以它可以引用它自己。你可以通过旁边创建一个弱引用来解决这个问题。

ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:...];
__weak ASIHTTPRequest *wrequest = request;

[request setCompletionBlock:^{
    NSDictionary *jsonDictionary = [[CJSONDeserializer deserializer] deserialize:wrequest.rawResponseData error:nil];
    // ...
    }];

扫码关注云+社区