首页 文章

那个时刻究竟是在NSOperation上执行的completionBlock吗?

提问于
浏览
2

我只是想知道在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"];
    }
}];

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

1 回答

  • 0

    来自文档:

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

    因此,您无法保证在从队列中删除操作之前或之后调用它 . 它是在触发器之后发送的,用于从队列中删除操作(因为操作已完成),但这两件事之间实际上存在竞争 .

    如果您正在询问操作队列本身以确定状态,那么您最好的选择是将您的考虑推向主runloop的下一次迭代 .

相关问题