objective-c - Objective c - 取消 dealloc 中的操作

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

我试图了解当操作的完成 block 中引用对象时,让对象在其 dealloc 方法中取消网络操作是否是一个好主意。

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

我有一个带有属性pictureUser对象,User有一个[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 方法将创建(并排队到 NSOperationQueue)一个 NSOperation,它会及时启动 NSURLConnection > 下载图像。当操作成功完成时,将调用成功 block 。

我使用 weakSelf 因为我不希望该 block 保留我的 User 对象(并防止其被释放),我希望用户负责取消现有操作(如果存在)当他被释放时。
所以 User dealloc 方法如下所示:

- (void)dealloc
{    
    [[AppClient sharedClient] cancelAllCommandsForSender:self];

    [super dealloc];
}

但似乎虽然我在 dealloc 方法中取消了操作,但有时在用户获取 dealloc 之后调用成功 block ,并且我得到 EXC_BAD_ACCESSweakSelf.picture = downloadImage

为什么会发生这种情况?是否该操作即使被取消也会尝试完成连接?

我知道如果我在 block 中只使用 self 而不是weakSelf,这种情况就不会发生,因为 block 将保留 User。但我不想要这种行为,我希望用户在释放时立即得到dealloc,即使存在获取操作。

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

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

还是不知道如何解决这个问题..

最佳答案

[[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
       } 
     }

关于objective-c - Objective c - 取消 dealloc 中的操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11412587/

相关文章:

ios - UIBUtton : what is it and how to remove it? 标题标签上的小黑边

ios - Xcode IAP SKProductsRequest 启动方法调用不在输出窗口中显示异常

iOS - 将点从一个坐标系转换为另一个坐标系

ios - Ionic - 为 Windows 上的 IOS 构建(适用于最新的 IOS 和 Ionic)

ios - Objective-C block : How to set an object to nil which uses block-based callback mechanism?

objective-c - ios pList 安全

iphone - 点击时如何让 UIButton 执行我的类方法?

ios - 如何使用 Xcode51_Be​​ta 在 iOS 7.1 beta 设备中编译应用程序

swift - 为什么我的 Objective-C block 在传递给 Swift 函数时没有显示?

ios - __destroy_helper_block_ 上的 Objective-C 崩溃