Я хочу синхронизировать некоторые данные с веб-службой. Для каждого элемента я должен выполнить асинхронный вызов.Ждите много асинхронных вызовов для выполнения обратного вызова
Я хочу, чтобы был завершен блок завершения, когда каждый элемент был синхронизирован. Для каждого элемента я могу выполнить блок завершения. Теперь я не знаю, как это сделать.
Это интерфейс:
-(void) synchronizeItemsOnComplete:(CompleteBlock) block {
NSArray* items = // get items
for (int i = 0, n = [items count]; i < n; i++) {
[self synchronizeItem:[items objectAtIndex:i] onComplete:^{
// What do do here?
}];
}
// And/or here?
}
-(void) synchronizeItemOnComplete:(CompleteBlock) block {
// do something
block();
}
Как я могу ждать для синхронизации, а затем выполнить блок?
Я пытался что-то вроде этого:
NSArray* items = // get items
__block int countOfItemsUntilDone = [items count];
for (int i = 0, n = countOfItemsUntilDone; i < n; i++) {
[self synchronizeItem:[items objectAtIndex:i] onComplete:^{
countOfItemsUntilDone--;
}];
}
dispatch_queue_t queue = dispatch_queue_create("wait for syncing", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
while (countOfItemsUntilDone > 0) {
usleep(1000); // wait a little bit
}
block();
});
dispatch_release(queue);
Но я думаю, что это очень плохой способ. Есть идеи?
Ох ... Я не сделал этого ясно. Тот метод synchronizeItemImage запускает асинхронный запрос через RESTKit. Таким образом, для выполнения этого метода async или с 'waitUntilDone:' вероятно, не получится. Чтобы избежать уменьшения количества разделяемой памяти в разных потоках, я мог бы выполнить блок из решения Криса Деверо в очереди последовательной отправки или это тоже плохо? – Obenland
Ох. В этом случае, пока обработчики завершения вызываются в основном потоке, вы можете просто уменьшить некоторую переменную. Или лучше, уменьшите свойство на своем windowController или делегировании приложения и используйте уведомления KVO, чтобы узнать, когда он достигнет нуля. – iluvcapra