我需要计算一个代价高昂的值。在计算完成后,我想运行一个完成处理程序块:
-(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);
});
});
}
非常标准。
现在,我希望能够重复调用此函数,而不需要重新排队costlyCalculation
。如果costlyCalculation
已经在运行,我想只保存完成块,并在costlyCalculation
完成后使用相同的result
调用它们所有。
是否可以使用GCD或NSOperationQueue简单实现这一点?或者我应该将完成块存储在一个NSArray
中并自己调用它们?如果我这样做,我需要在这个数组周围放置什么样的同步?
更新
使用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
是否已经在运行,且不需要排队工作,我该怎么办?
result
,因为在第一次运行时会有多个请求快速连续到达,这将导致对costlyCalculation
的重复调用。也许用 BOOLs 标记开始和结束是正确的方法。感谢您的建议。 - bcattlecostlyCalculation
,然后保留结果(如果结果始终相同,则保留结果比每次计算更可取)。 - Rob SandersgenerateCGImagesAsynchronouslyForTimes
方法生成图片,这些图片需要在屏幕上的不同位置的多个不同图层中重复使用。所以如果在generateCGImagesAsynchronouslyForTimes
正在运行时有一个新图层出现,我希望在这个新图层中重复使用相同的图片而不重新运行图像生成器。 - bcattlegenerateCGImagesAsynchronouslyForTimes
没有缓存的概念,因此如果在函数运行时有多个相同的调用,则将它们包装在一起的层中是合理的。或者我误解了你的意思? - bcattlegenerateCGImagesAsynchronouslyForTimes
。 - bcattle