我只是想知道在NSOperationQueue拥有的NSOperation上执行completionBlock的确切时刻。
在我的最新项目,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)
来自文档:
无法保证完成块的确切执行上下文,但通常是辅助线程。因此,您不应该使用此块来执行任何需要非常特定的执行上下文的工作。
因此,您无法保证在从队列中删除操作之前或之后调用它。在触发器之后发送它以从队列中删除操作(因为操作已完成),但这两件事之间实际上存在竞争。
如果您要询问操作队列本身以确定状态,那么最好的选择是将您的考虑推到主runloop的下一次迭代。