与this question非常相似,我正在尝试转换使用ASIHTTPRequest
&的项目ASIFormDataRequest
到ARC。
在我的视图控制器类中,我经常在完成块中引用并使用request
对象的属性(查看响应代码,响应数据等):
__block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:SOME_URL]];
[request setCompletionBlock:^{
if([request responseStatusCode] == 200) ....etc
转换为ARC时,我收到警告:
在此区块中强烈捕获'请求'可能会导致a 保留周期
这样做的正确方法是什么?
另一个SO用户在前一个帖子中指出,简单地添加__weak
可能会导致请求在块完成之前被释放,我认为这是真的。
如何在ARC下的完成/故障块中正确引用这些属性?
答案 0 :(得分:27)
(我读了你对其他问题的评论)
在使用ASIHTTPRequest
实现更多模块之后,我了解到最好的方法是对请求对象保持strong
引用。在您的情况下,您可以这样做:
self.request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:SOME_URL]];
__weak ASIFormDataRequest *weakRequest = self.request; // __block directive not needed since we only access the instance's properties.
[self.request setCompletionBlock:^{
if([weakRequest responseStatusCode] == 200)
// ...
这样,即使您开始请求(例如取消请求),您仍然可以控制self.request
。当您准备发布请求时,可以执行self.request = nil;
,可能在完成块或self.request
的父对象的清理方法中。{/ p>
<强>更新强>
如果你的目标是iOS 5之前的版本,那么共同点就是:使用__unsafe_unretained
代替__weak
。这没关系,因为查看ASIHTTPRequest.m
,其nil
中的块dealloc()
已被删除(即它们不应被执行)。虽然我还没有测试过,所以请确保仍然启用NSZombies进行测试。
注意:强>
取消ASIHTTPRequest
对象的唯一安全方法是调用其clearDelegatesAndCancel
方法。当我刚刚使用普通的cancel
时,我被一些令人讨厌的错误所困扰。
答案 1 :(得分:2)
如果您的目标是5.0之前的iOS版本,则不包括weak
支持:
__unsafe_unretained __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
答案 2 :(得分:1)
我发现这个答案很有帮助:https://stackoverflow.com/a/7735770/133875
它表示使用__unsafe_unretained
以及__block