我有一个NSInvocationOperation,可以在后台下载并解析一系列NSXMLDocuments到我的UI响应。
我尝试停止调用操作是调用我的NSOperationQueue的cancellAllOperations。但似乎这不会阻止调用的执行。
关于如何解决这个问题的任何想法?
答案 0 :(得分:11)
更新:当我这样做时,仪器显示泄漏 - 充足。 谨慎行事!我将此保留在这里,以防我实际上正在处理某事并且其他人可以弄清楚如何克服泄漏障碍。
这是一个扭曲的想法,当我输入时我正在重新尝试:
将操作设置为 NSInvocationOperation 的 initWithTarget:selector:object:方法的对象。假设您已经有 NSOperationQueue (我们称之为队列):
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 ,我会知道这是否真的有效。 :)
答案 1 :(得分: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];
然后在targetObj实现
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
观察由NSOperationQueue的cancellAllOperations改变的isCancelled。 你可以在这里设置一个私有标志,targetMethod可以检查它并在需要时取消。
答案 2 :(得分:5)
上面的帖子很棒,但更直接地回答了原来的问题:看来你无法阻止NSInvocationOperation对象,因为它不支持取消。你将不得不继承它。
答案 3 :(得分:3)
由NSOperation
对象实现实际停止它正在做什么,清理并在收到通知已被取消时退出。要取消队列上所有操作的消息传递将导致队列停止使新操作出列以运行,并将取消消息发送到当前正在运行的任何操作。
在您的操作主要方法中,您应该检查isCancelled
并在实际取消时处理该状态。
有关详细信息,请参阅“线程编程指南”中的Creating and Managing Operation Objects。