如何停止NSInvocationOperation?

Ear*_*dad 9 cocoa multithreading pyobjc objective-c

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

我试图停止调用操作是调用我的NSOperationQueue的cancellAllOperations.但似乎这不会阻止调用的执行.

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

Joe*_*rea 11

更新:仪器显示泄漏 - 当我这样做时充足.谨慎行事!我保留这个,以防万一我真正做某件事,其他人可以弄明白如何克服泄漏障碍.

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

设定的操作作为对象NSInvocationOperationinitWithTarget:选择器:对象:方法.假设你已经有了一个NSOperationQueue(我们称之为队列):

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

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

然后,在您的操作方法中,将对象强制转换并根据需要对isCancelled进行检查.例如:

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

确保你的选择器在initWithTarget:...调用后以冒号结束,因为你现在将传入一个对象.

到现在为止还挺好.现在,如果我可以强制取消所有操作,我会知道这是否真的有效.:)


小智 8

您需要检查NSInvocationOperation isCancelled是否为YES.要在NSInvocationOperation中执行此操作,您可以使用键值观察:

运行操作时,将对象添加为NSInvocationOperation isCancelled observer:

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];
Run Code Online (Sandbox Code Playgroud)

然后在targetObj中实现

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
Run Code Online (Sandbox Code Playgroud)

要注意由NSOperationQueue的cancellAllOperations改变isCancelled.您可以在此设置私有标志,targetMethod可以检查它并在需要时取消.


Eig*_*ght 5

上面的帖子很棒,但更直接地回答了原来的问题:看来你无法阻止NSInvocationOperation对象,因为它不支持取消.你将不得不继承它.


Jas*_*oco 3

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

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

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