9

我有一个 NSInvocationOperation 可以在后台下载并解析一系列 NSXMLDocuments 以响应我的 UI。

我停止调用操作的尝试是调用我的 NSOperationQueue 的 cancelAllOperations。但这似乎不会停止调用的执行。

关于我将如何解决这个问题的任何想法?

4

4 回答 4

11

更新:当我这样做时,仪器会显示大量泄漏。谨慎行事!我把这个留在这里,以防我真的在做某事,而其他人可以弄清楚如何克服泄漏障碍。

这是一个扭曲的想法,我在输入以下内容时正在重新尝试:

将操作设置为NSInvocationOperationinitWithTarget:selector:object:方法的对象。假设你已经有一个NSOperationQueue(我们称之为queue):

NSInvocationOperation *operation = [NSInvocationOperation alloc];
operation = [operation initWithTarget:self selector:@selector(myOperation:) object:operation];
[queue addOperation:operation];
[operation release];

请注意,我们必须将 alloc 分解为它自己的调用。否则我们无法将对象设置为操作

然后,在您的操作方法中,将对象投射回去并根据需要对isCancelled进行检查。例如:

  - (void)myOperation:(id)object {
    NSInvocationOperation *operation = (NSInvocationOperation *)object;
    if ([operation isCancelled]) return;
    ...
  }

确保您的选择器在initWithTarget:...调用中以冒号结尾,因为您现在将传入一个对象。

到现在为止还挺好。现在,如果我可以强制cancelAllOperations,我会知道这是否真的有效。:)

于 2009-08-11T21:03:42.130 回答
8

您需要检查 NSInvocationOperation isCancelled 是否为 YES。要在 NSInvocationOperation 中做到这一点,您可以使用 Key Value Observing:

在运行操作时将您的对象添加为 NSInvocationOperation isCancelled 观察者:

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:<targetObj> selector:@selector(<targetMethod>) object:nil];
[operation addObserver:<targetObj> forKeyPath:@"isCancelled" options:NSKeyValueObservingOptionNew context:nil];
[operQueue addOperation:operation];
[operation release];

然后在 targetObj 中实现

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

观察 isCancelled 是否被 NSOperationQueue 的 cancelAllOperations 更改。您可以在此处设置私有标志,targetMethod 可以检查它并在需要时取消。

于 2010-06-02T11:16:11.113 回答
5

上面的帖子很棒,但更直接地回答了原始问题:您似乎无法停止 NSInvocationOperation 对象,因为它不支持取消。你将不得不对它进行子类化。

于 2009-05-01T20:39:38.493 回答
3

由您的NSOperation对象的实现来实际停止它正在做的事情,清理并在收到通知它已被取消时退出。您要取消队列上的所有操作的消息将导致队列停止将要运行的新操作出列,并将取消消息发送到当前正在运行的任何操作。

在您的操作的主要方法中,您应该在isCancelled实际取消时检查并处理该状态。

有关详细信息,请参阅线程编程指南中的创建和管理操作对象

于 2009-04-18T06:22:07.727 回答