多次运行完成阻止,一个接一个地运行。

时间:2015-05-28 22:43:45

标签: objective-c

我有一段代码(带有完成块),我想多次运行(来自FOR循环),但我只希望逐个进行操作。

尝试更好地解释一下......(最大并发操作= 1,For()循环中的项目= 3)

  1. 在第0项开始为()
  2. 为项目0
  3. 启动操作
  4. 完成第0项的操作
  5. 项目1的循环For()
  6. 开始操作以获取第1项
  7. 完成第1项的操作
  8. 第2项的循环()(
  9. 启动第2项的操作
  10. 完成第2项的操作
  11. 在第2项中结束()
  12. 已经制定了这个解决方案,但它似乎一次又一次地运行而不是一个接一个地运行..

        // Batch download
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        queue.maxConcurrentOperationCount = 1;
    
        for (Item *item in ItemArray) {
            [queue addOperationWithBlock:^{
                if (![[ItemClient sharedClient] isCachedItem:item]) {
                    // Item not yet cached
    
                    [[ItemClient sharedClient] cacheItem:item completion:^(NSError *error) {
                            // Complete, next in FOR loop
                    }];
                } else {
                    // Item already cached
                    // Complete, next in FOR loop
                }
            }];
        }
    

1 个答案:

答案 0 :(得分:0)

我认为[ItemClient cacheItem:completion:]在调用完成处理程序之前会执行一些长时间的工作,而这是您在开始下一个请求之前要等待的内容。

您的代码不在等待完成处理程序,这就是请求显然并行发生的原因。在允许队列中的下一个操作开始之前,您需要等待完成调用。

最简单的方法可能是重写[ItemClient cacheItem:completion:]以使其同步。换句话说,它只是完成工作,阻塞当前线程,并且不需要完成参数。 NSOperationQueue无论如何都会将这些操作放到后台线程中,所以你可以使用该线程来完成你的工作。

或者,您可以使用信号量来阻止,直到完成回调发生:

dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[[ItemClient sharedClient] cacheItem:item completion:^(NSError *error) {
    dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);