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

bar*_*oon 21 iphone objective-c asihttprequest ios automatic-ref-counting

此问题非常相似,我正在尝试将使用ASIHTTPRequest&的项目转换ASIFormDataRequest为ARC.

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

__block  ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:SOME_URL]];    
[request setCompletionBlock:^{   

    if([request responseStatusCode] == 200) ....etc
Run Code Online (Sandbox Code Playgroud)

转换为ARC时,我收到警告:

在此块中强烈捕获"请求"可能会导致保留周期

这样做的正确方法是什么?

另一个SO用户在前一个帖子中指出,简单添加__weak可能会导致请求在块完成之前被释放,我认为这是真的.

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

Joh*_*pia 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)
    // ...
Run Code Online (Sandbox Code Playgroud)

这样,您self.request甚至可以在启动请求后进行控制(例如取消).您可以self.request = nil;在准备好发布请求时执行操作,可能在完成块或self.request父对象的清理方法中.

更新:

如果您的目标是iOS 5之前,那么共同点就是:使用__unsafe_unretained而不是__weak.这是可以的,因为看一下ASIHTTPRequest.m,这些块在其中被nil删除dealloc()(即它们不应该被执行).虽然我还没有测试过,所以请确保仍然启用NSZombies进行测试.

注意:

取消ASIHTTPRequest对象的唯一安全方法是调用其clearDelegatesAndCancel方法.当我刚刚使用普通的bug时,我被一些讨厌的错误所困扰cancel.