アプリが実行しているスレッドの数を制御してバランスをとる方法、スレッドの制限に達したためにアプリがブロックされないようにスレッドの数を制限する方法は?
ここで私は次の可能な答えを見ました:「メイン同時キュー(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など)
- 低速で狭いキューは、多数の保留中のジョブに圧倒される可能性があります。
- 2番目の問題もキャンセルの問題を引き起こす可能性があります。シリアルキューで実行を待機しているジョブが100個ある場合、それらを一度にキャンセルすることはできません。
明白でばかげた解決策は、機密性の高いdispatch_asyncメソッドをdispatch_syncに置き換えることですが、それは間違いなく私が好きではないものです。
このような状況で推奨されるアプローチは何ですか?
「NSOperationQueueを使用する-同時操作の数を制限できる」よりも賢い答えが存在することを願っています(同様のトピック:NSOperationQueueDefaultMaxConcurrentOperationCountを持つスレッドの数)。
更新1:唯一の適切なパターンは次のとおりです:最大操作制限が設定されたNSOperationQueueベースの同時キューでNSOperationsにラップされたこれらのブロックを実行して同時キューにブロックのすべてのdispatch_asyncを置き換えることです(私の場合は最大操作制限も設定されていますAFNetworkingがすべての操作を実行するNSOperationQueueベースのキュー)。