it-swarm.com.de

Konsistente Dispatch-Warteschlange: Absturz com.Apple.root.default-qos.overcommit

Hat jemand Erfahrung gehabt, diese Abstürze zu diagnostizieren? Ich habe einen einzelnen Benutzer, der sie konsistent erhält, und obwohl ich einen iOS-Beitrag gefunden habe, stürzt meine App bei derselben Art von Vorgang nicht ab.

33
JeremyLaurenson

Grund:

in iOS/tvOS gibt es Warteschlangen/Threads, jeder Thread hat einen eigenen Typ oder eine eigene Priorität, die auch als "Quality of Service" oder kurz "QOS" bezeichnet wird, dh die Dringlichkeit, mit der die CPU diesen Thread handhaben soll, die Möglichkeiten sind:

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

wenn Sie zu viele Tasks gleichzeitig in derselben Warteschlange ausführen, werden Sie vom Betriebssystem darüber informiert, dass alle Tasks nicht gleichzeitig mit derselben Priorität ausgeführt werden können (die Größe des Stapels ist für jede Warteschlange begrenzt). , da steht dort "OverCommit", was bedeutet, dass Sie die Warteschlange (in Ihrem Fall die Warteschlange "Default-QOS") überschrieben haben. Sie wird beendet, da sie zu diesem Zeitpunkt keine weiteren Aufgaben empfangen kann und sie auf die gewünschte Weise ausführen kann.

Lösung:

sie sollten zuerst den Befehl "dispatch_async" finden, der diesen Absturz verursacht, und dann eine der anderen Warteschlangen verwenden (dh, Sie erwarten eine langsamere Antwort als erwartet für diese Aufgabe).

normalerweise denken Entwickler nicht darüber nach und verwenden einfach die Hauptwarteschlange, die die Standardpriorität/Warteschlange ist:

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

um dies zu beheben (wenn die App Sie benachrichtigt, dass Sie die Hauptwarteschlange überbeansprucht haben), ändern Sie sie in eine der anderen Warteschlangen wie folgt:

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")
})

wenn Sie keine Hintergrundausführung (oder Parallelausführung) benötigen, können Sie den dispatch_async-Befehl sogar ganz ignorieren und Ihre Befehle einfach wie folgt ausführen:

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

Schreibe Shaybcs Antwort in Swift 3 neu:

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

Für Swift 3 verwenden:

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