目标c - 取消dealloc中的操作

时间:2012-07-10 11:42:56

标签: objective-c ios objective-c-blocks nsoperation

我正在尝试理解,当在操作的完成块中引用Object时,让Object取消网络操作是否是dealloc方法是一个好主意。

我将尝试用一个例子来解释:

我有一个User对象,其属性为pictureUser有一个[self fetchPictureFromServer]

- (void)fetchPictureFromServer
{
    NSDictionary *cmdParameters = ...; // set parameters

    __block User *weakSelf = self;  

    [[AppClient sharedClient] sendCommand:@"getpicture" parameters:cmdParameters success:^(AFHTTPRequestOperation *operation, id response) 
     {  
        // success  
        UIImage *downloadedImage = ...; // get image from response  

        weakSelf.picture = downloadedImage; // set image to user's picture property
     }

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        // failed 
    }];

sendCommand方法会创建(NSOperationQueueNSOperation NSURLConnection,及时发起weakSelf下载图片。操作成功完成后,将调用成功块。

我正在使用- (void)dealloc { [[AppClient sharedClient] cancelAllCommandsForSender:self]; [super dealloc]; } ,因为我不希望该块保留我的User对象(并防止它被dealloc),我希望用户将负责取消现有的操作(如果存在)当他得到dealloc时 因此,用户dealloc方法如下所示:

EXC_BAD_ACCESS

但似乎虽然我正在取消dealloc方法中的操作,但有时成功块在用户获得dealloc之后被称为,并且我在行{weakSelf.picture = downloadedImage中得到{{1}} 1}}。

为什么会这样?可能是操作尝试完成连接,即使它被取消了吗?

我知道如果我在块中仅使用self而不是weakSelf,则不会发生这种情况,因为该块将保留用户。但我不想要这种行为,我希望用户在发布时立即获得dealloc,即使存在提取操作。

更新: 的 我注意到操作状态isFinished = YES,似乎对于我使用的库,当一个操作完成时,它不会立即执行成功块,而是使用主队列dispatch_async成功块。

所以恰当的是:
1.用户获取图像 - >创建一个操作
2.操作完成 - > dispatch_async成功块(仍未执行)
3.在执行成功块之前,用户dealloc - >取消他所有的操作(但不是步骤1中的操作,因为它处于isFinished状态)
4.现在执行成功块 - >尝试引用用户时,我得到EXC_BAD_ACCESS。

仍然不知道如何解决这个问题。

1 个答案:

答案 0 :(得分:2)

[[AppClient sharedClient] sendCommand:@"getpicture" parameters:cmdParameters success:^(AFHTTPRequestOperation *operation, id response) 
     {  
       if(!operation.isCancelled)
       { 
       // success  
        UIImage *downloadedImage = ...; // get image from response  

        weakSelf.picture = downloadedImage; // set image to user's picture property
       } 
     }