NSOperationQueue和dealloc被调用和崩溃App的问题

时间:2010-09-03 01:34:02

标签: iphone exc-bad-access nsoperation dealloc nsoperationqueue

我在队列中创建了一个NSOperation,如下所示:

ImageLoadingOperation *operation = [[ImageLoadingOperation alloc] initWithImageURL:url target:self action:@selector(didFinishLoadingImageWithResult:)];
[operationQueue addOperation:operation];
[operation release];

这样可以正常工作但是如果在操作完成之前弹出视图,则应用程序崩溃并显示“EXC_BAD_ACCESS”

我试图通过调用cancelAllOperations取消操作队列,但由于它已在进程中,因此不会阻止应用程序崩溃。 docos说,如果操作正在运行,那么由操作来检测它是否被取消并做出适当的响应但不太确定我将如何实现它?

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

View调用某个网络然后回调是一个普遍的问题。

我的解决方案是您可以在调用操作之前保留视图。然后,当操作完成时,您将释放视图。

- (void)longTask {
   [self retain];
}

- (void)longTaskDidFinish {
   // do something if you want
   [self release];
}

答案 1 :(得分:0)

您必须覆盖"取消"在ImageLoadingOperation类中操作,或让ImageLoadingOperation将自身添加为KVO观察者,并取消"取消"属性。在那里 - 您可以智能地取消您的操作,使其不会崩溃。

此外,如果您的ImageLoadingOperation在后台运行,那么将您对视图的访问以某种方式推迟到主线程(所有绘图都会发生)将更明智。您可以使用dispatch_sync(dispatch_get_main_queue(),^ {});或甚至执行SelectorOnMainThread以实际访问相关视图。

你知道 - 使用操作队列的重点是删除依赖关系,让事情并行运行,但是你的操作必须与视图系统的更改同步,并且必须设计为完整性和健壮性。

答案 2 :(得分:0)

您可以在调用操作回调之前保留视图,如上面提到的vodkhang。但这会不必要地延长视图的使用寿命,因为自弹出视图后,您不希望操作再继续。
下面是关于您应该如何响应取消命令的草图:

- (void)start{
    if(self.isCancelled){
       [self markAsFinished];
       return;
    }
    //start your task asynchronously
}


//If you want to cancel the downloading progress immediately, implement your own 'cancel' method
- (void)cancel{
    [super cancel];
    if(self.isExecuting){
       {
          ......
          cancel load process
          ......
       }
       [self markAsFinished];
    }
}

- (void)markAsFinished{
    ......
    change 'finished' to YES'  generate KVO notifications on this key path
    change 'executing' to 'YES'; generate KVO notification on this key path
    ...... 
}

此草图基于ASIHTTPRequest网络库,以及  关于如何响应取消命令有一个official guide