Мне нужно рассчитать дорогостоящее значение. После вычисления этого значения я хотел бы запустить блок обработки завершений:Objective-C wait для асинхронных операций и обработчиков завершения очереди.
-(void) performCostlyCalculationWithCompletionHandler:(void (^)(void)complete
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
id result = [self costlyCalculation];
dispatch_async(dispatch_get_main_queue(), ^{
complete(result);
});
});
}
Довольно стандартный.
Теперь, я хотел бы иметь возможность называть эту функцию повторно, без повторного enqueueing costlyCalculation
. Если costlyCalculation
уже работает, я хотел бы просто сохранить блокировки завершения и назвать их всех одним и тем же result
после завершения costlyCalculation
.
Есть ли простой способ сделать это с помощью GCD или NSOperationQueue? Или я должен просто хранить блоки завершения в NSArray
и называть их сам? Если я это сделаю, какую синхронизацию мне нужно установить вокруг этого массива?
UPDATE
Я могу сблизиться с dispatch_group_notify
. В принципе, я могу епдиеий рабочие блоки и епдиеий все обработчик завершения для запуска после группы:
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_async(group, queue, ^(){
// Do something that takes a while
id result = [self costlyCalculation];
dispatch_group_async(group, dispatch_get_main_queue(), ^(){
self.result = result;
});
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^(){
complete(result);
});
Этой работы, но как я могу сказать, если costlyCalcuation
уже работает и не епдиеяя работу, если я не нужно?
Не могли бы вы сохранить результат как ivar, а затем проверить существование «результата» перед выполнением «costlyCalculation» или просто пометить начало и конец функции с помощью BOOL, а затем, если функция запущена, добавьте блок к массиву, как указано в вашем q, и вызвать все блоки в очереди после завершения вычисления. Я уже делал обе эти вещи, если вам нужен какой-то код. –
Не хотите проверять «результат» заранее, потому что несколько запросов будут выполняться быстро, пока он работает в первый раз, что приведет к дублированию вызовов «costlyCalculation». Возможно, обозначение начала и конца BOOLs - правильный путь. Спасибо за предложение. – bcattle
Конечно, я использую 'AVAssetImageGenerator' для создания эскизов из актива. Затем миниатюры вставляются в несколько «CALayers» в разных местах на экране. Видимые слои могут появляться и исчезать при запуске 'AVAssetImageGenerator'. – bcattle