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

非常类似于这个问题 ,我试图将使用ASIHTTPRequestASIFormDataRequest的项目转换为ARC。

在我的视图控制器类中,我经常引用并使用完成块中的request对象的属性(查看响应代码,响应数据等):

 __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:SOME_URL]]; [request setCompletionBlock:^{ if([request responseStatusCode] == 200) ....etc 

当转换到ARC我得到的警告:

在这个区块强烈的捕获'请求'很可能会导致一个保留周期

什么是正确的方法来做到这一点?

另一个SO用户在上一个线程中注意到,简单地添加__weak可能会导致请求在块完成之前被释放,我相信这是正确的。

如何在ARC下的完成/失败块中正确引用这些属性?

(我读了你的评论到另一个问题)

在使用ASIHTTPRequest实现了几个模块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的父对象的清理方法。

更新:

如果您的目标是iOS 5之前的版本,那么共同点就是:使用__unsafe_unretained而不是__weak 。 这是可以的,因为看ASIHTTPRequest.m ,这些块在其dealloc()没有被删除(即它们不应该被执行)。 虽然我还没有testing,所以一定要仍然testing启用NSZombies。

注意:

取消ASIHTTPRequest对象的唯一安全方法是调用其clearDelegatesAndCancel方法。 当我使用简单的cancel时,我被一些令人讨厌的错误所困扰。

如果您在5.0之前定位iOS版本,则不包括weak支持:

 __unsafe_unretained __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url]; 

我发现这个答案是有帮助的: https : //stackoverflow.com/a/7735770/133875

它说使用__unsafe_unretained以及__block