1

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

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

这工作正常,但如果视图在操作完成之前弹出应用程序崩溃“EXC_BAD_ACCESS”

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

有任何想法吗?

4

3 回答 3

1

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

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

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

- (void)longTaskDidFinish {
   // do something if you want
   [self release];
}
于 2010-09-03T02:02:25.663 回答
0

您将不得不覆盖 ImageLoadingOperation 类中的“取消”操作,或者让 ImageLoadingOperation 将自身作为 KVO 观察者添加到“取消”属性中。在那里 - 您可以以不会崩溃的方式智能地取消您的操作。

此外,如果您的 ImageLoadingOperation 在后台运行,最好将您对视图的访问推迟到主线程(所有绘图发生的地方)。您可以使用 dispatch_sync(dispatch_get_main_queue(), ^{}); 甚至 performSelectorOnMainThread 以实际访问相关视图。

你看 - 使用操作队列的全部意义在于消除依赖关系,让事情并行运行,但是你的操作必须与视图系统的变化同步,并且必须为完整性和健壮性而设计。

于 2015-10-24T07:32:54.373 回答
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 网络库,并且有一个关于如何响应取消命令的官方指南。

于 2015-11-16T03:20:50.077 回答