web-dev-qa-db-ja.com

一貫性のあるディスパッチキュー:com.Apple.root.default-qos.overcommit crash

これらのクラッシュを診断した経験はありますか? 1人のユーザーが一貫してそれらを取得しています。iOS関連の投稿を見つけましたが、同じ種類の操作でアプリがクラッシュしません...

35
JeremyLaurenson

理由:

iOS/tvOSにはキュー/スレッドがあり、各スレッドには「サービス品質」または略して「QOS」とも呼ばれる独自のタイプまたは優先度があります。これは、CPUがこのスレッドを処理する緊急度、次のとおりです。

  • QOS_CLASS_DEFAULT
  • QOS_CLASS_USER_INITIATED
  • QOS_CLASS_UTILITY
  • QOS_CLASS_BACKGROUND
  • QOS_CLASS_UNSPECIFIED
  • QOS_CLASS_USER_INTERACTIVE

同じキューで同時に多くのタスクを実行すると、OSは同じ優先度でこのすべてのタスクを同時に実行できないことを通知します(各キューのスタックのサイズには制限があります) 、そこには「OverCommit」と表示されます。これは、キュー(この場合は「Default-QOS」キュー)をオーバーコミットしたことを意味し、現時点ではこれ以上タスクを受信できず、必要な方法で実行できないため終了します.

解決策:

あなたがすべきことは、最初にこのクラッシュの原因となる「dispatch_async」コマンドを見つけてから、他のキューの1つを使用することです(それは、そのタスクに期待されるより遅い応答を期待することを意味します)、

通常、開発者はそれについて考えず、次のようにデフォルトの優先度/キューであるメインキューを使用します。

dispatch_async(dispatch_get_main_queue()) {
    // some task to perform
    print("This is my task")
}

これを修正するには(アプリがメインキューをオーバーコミットしたことを通知した場合)、次のように他のキューのいずれかに変更します。

let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
    // some task to perform
    print("This is my task")
})

バックグラウンド(または並列)実行が不要な場合は、dispatch_asyncコマンドを完全に無視して、次のようなコマンドを実行することもできます。

// some task to perform
print("This is my task")
21
Shaybc

Shaybcの答えをSwift 3:

DispatchQueue.global(qos: .background).async {
  // some task to perform
  print("This is my task")
})
3
Bill Chan

Swift 3を使用:

DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async { 
    // ... 
}
2
Simon Fakir