2

我只是想知道在NSOperationQueue所拥有的NSOperation上执行completionBlock的具体时刻。在NSOperation上执行完成块是在哪一刻?

在我的最新项目Amazon S3的客户端(https://github.com/StudioIstanbul/SIAFAWSClient)上,我使用带有completionBlock的NSOperation来处理对Amazon REST API的请求。客户端可以通过名为isBusy的主类上的属性来监视所有预定请求的状态。在我的操作的完成块中,如果在我的NSOperationQueue中没有安排其他操作,我将此属性的值设置为NO。我现在发现,在少数情况下,当CompletionBlock被调用时,我的当前NSOperation仍然包含在我的NSOperationQueue中。这对我来说似乎有点奇怪。我最终在队列中检查了当前NSOperation的存在以解决这个问题,但从设计的角度来看这似乎没有必要。

__weak AWSOperation* thisOperation = operation; 
[operation setCompletionBlock:^{ 
    if (self.operationQueue.operationCount <= 0 
     || (self.operationQueue.operationCount == 1 
     && [self.operationQueue.operations objectAtIndex:0] == thisOperation)) { 
     [self willChangeValueForKey:@"isBusy"]; 
     _isBusy = NO; 
     [self didChangeValueForKey:@"isBusy"]; 
    } 
}]; 

有没有人有关于此行为的更多信息?

回答

0

从文档:

为您完成块的确切执行上下文不能保证,但通常是一个辅助线程。因此,您不应该使用此块来执行任何需要特定执行上下文的工作。

因此,您不能保证在将操作从队列中移除之前或之后调用它。它是在触发器之后发送的,以便从队列中移除操作(因为操作已完成),但在这两件事之间实际上存在竞争。

如果您询问操作队列本身以确定状态,您最好的选择是将您的考虑推到主循环的下一个迭代中。

+0

但是这并不是说它不能保证在拆除手术后运行。我也很惊讶。 –

+0

它明确表示不能保证它的运行时间,因为它将运行的线程不能保证 – Wain

+0

是的,但是在运行的任何线程上,它可以在删除后启动。 –

相关问题