ASIHTTPRequest / ASIFormDataRequest - 在ARC下的块内引用请求对象

时间:2012-01-14 02:19:34

标签: iphone objective-c ios asihttprequest automatic-ref-counting

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下的完成/故障块中正确引用这些属性?

3 个答案:

答案 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