如何控制和平衡我的应用程序正在执行的线程数量,如何限制它们的数量以避免应用程序因为达到线程限制而阻塞?
在这里,我看到了以下可能的答案:“主并发队列(dispatch_get_global_queue)自动管理线程数”我不喜欢,原因如下:
考虑以下模式(在我的真实应用中,有更简单和更复杂的示例):
dispatch_queue_t defaultBackgroundQueue() {
return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
}
dispatch_queue_t databaseQueue() {
dispatch_queue_create("Database private queue", 0);
}
dispatch_async(defaultBackgroundQueue(), ^{
[AFNetworkingAsynchronousRequestWithCompletionHandler:^(data){
dispatch_async(databaseQueue(), ^{
// data is about 100-200 elements to parse
for (el in data) {
}
maybe more AFNetworking requests and/or processing in other queues or
dispatch_async(dispatch_get_main_queue(), ^{
// At last! We can do something on UI.
});
});
}];
});
这种设计经常导致以下情况:
- 由于达到线程限制,应用程序被锁定(类似于 > 64)
- 较慢且因此较窄的队列可能会因大量待处理的作业而不堪重负。
- 第二个也可能产生取消问题 - 如果我们有 100 个作业已经在串行队列中等待执行,我们不能一次取消它们。
显而易见且愚蠢的解决方案是用 dispatch_sync 替换敏感的 dispatch_async 方法,但它绝对是我不喜欢的方法。
对于这种情况,推荐的方法是什么?
我希望一个比“使用 NSOperationQueue - 它可以限制并发操作的数量”更聪明的答案确实存在(类似的主题:带有 NSOperationQueueDefaultMaxConcurrentOperationCount 的线程数)。
更新 1:唯一体面的模式是:是将所有 dispatch_async 的块替换为并发队列,并在基于 NSOperationQueue 的并发队列中运行包装在 NSOperations 中的这些块,并设置最大操作限制(在我的情况下,可能还设置了最大操作限制AFNetworking 在其中运行所有操作的基于 NSOperationQueue 的队列)。