我有一个带有NSOperationQueue的NSOperation,它有一堆子操作,有些是排队的。
我遇到了一个问题,即使在队列上调用cancelAllOperations后,我的main方法仍挂在waitUntilAllOperationsAreFinished上。
然后,当我设置完成标志时,我在取消时使用isFinished,它不再在取消的队列中备份。
- (BOOL)isFinished
{
return complete;
}
- (void)cancel
{
cancelled = YES;
complete = YES;
[_childOperationQueue cancelAllOperations];
}
这是正确的行为,取消的操作应该在技术上完成吗? 似乎NSOperation需要将isFinished设置为true才能将其删除,因为这可能会让它“清理”,但我不知道这里的协议是什么,谷歌没有透露太多。 / p>
答案 0 :(得分:4)
取消操作只需设置isCancelled
即可返回YES
。这意味着在您的NSOperation块中,您可以检查isCancelled
并防止不必要地执行任何工作(您需要自己实现此逻辑)。
您的主线程需要等待队列中的所有操作,但如果您的NSOperation块在执行任何操作之前检查isCancelled
,您应该快速完成所有排队操作,并且等待不应该很长
答案 1 :(得分:3)
如果您正在编写并发操作(即isConcurrent
方法返回YES
),我有两个观察结果:
当您更改要完成的操作状态时,您必须手动执行相应的isFinished
KVN。因此,在更改状态变量之前,请致电willChangeValueForKey
,然后在更改后调用didChangeValueForKey
。
有很多方法可以实现这一点,但我定义了finished
和executing
属性,如下所示:
@property (nonatomic, readwrite, getter = isFinished) BOOL finished;
@property (nonatomic, readwrite, getter = isExecuting) BOOL executing;
我使用那些合成的getter,但写了做适当KVN的setter:
@synthesize finished = _finished;
@synthesize executing = _executing;
- (void)setExecuting:(BOOL)executing
{
if (_executing != executing) {
[self willChangeValueForKey:@"isExecuting"];
_executing = executing;
[self didChangeValueForKey:@"isExecuting"];
}
}
- (void)setFinished:(BOOL)finished
{
if (_finished != finished) {
[self willChangeValueForKey:@"isFinished"];
_finished = finished;
[self didChangeValueForKey:@"isFinished"];
}
}
然后,当我想完成操作时,我调用一个这样的方法:
- (void)completeOperation
{
self.executing = NO;
self.finished = YES;
}
这导致isExecuting
和isFinished
的KVN(以及确保我的合成getter也返回适当的值)。如果您不这样做,您的操作可能永远不会完成。
在取消操作方面,有两种方法:
您可以定期检查[self isCancelled]
(一种非常常见的模式,如果你有一个循环或一些被重复调用的方法,例如基于委托的连接/会话中的didReceiveData
),如果是这样,做你需要的任何清理,然后完成操作(上面的completeOperation
方法)。
如果您没有任何地方可以定期检查取消状态,您希望覆盖cancel
方法,该方法会执行您需要的任何清理工作,请拨打[super cancel]
但是还确保操作也完成(例如,如果操作正在执行,则调用completeOperation
。)
我还start
检查取消状态:
- (void)start
{
if ([self isCancelled]) {
self.finished = YES;
return;
}
self.executing = YES;
// start my operation
}
除此之外,如果不了解操作的核心内容(NSURLConnection
?NSURLSession
?还有什么其他内容,很难再为您提供建议? )。
有关详细信息,请参阅Concurrency Programming Guide: Operation Queues中的配置并发执行操作。