web-dev-qa-db-fra.com

File d'attente Dispatch cohérente: crash de com.Apple.root.default-qos.overcommit

Quelqu'un a-t-il déjà diagnostiqué ces accidents? J'ai un utilisateur unique qui les reçoit régulièrement, et bien que j'ai trouvé un article lié à iOS, mon application ne plante pas sur le même type d'opération ...

33
JeremyLaurenson

Raison:

dans iOS/tvOS, il existe des files d'attente/threads, chaque thread a son propre type ou priorité, également appelé "qualité de service" ou "QOS", ce qui signifie le niveau d'urgence auquel le processeur doit traiter ce thread, les possibilités sont:

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

une fois que vous exécutez trop de tâches en même temps dans la même file d'attente, le système d'exploitation vous avertit qu'il ne peut pas effectuer toutes ces tâches en même temps avec la même priorité (la taille de la pile est limitée pour chaque file d'attente). "OverCommit", ce qui signifie que vous avez surchargé la file (dans votre cas, la file "Default-QOS") et qu'elle se ferme car elle ne peut pas recevoir plus de tâches pour l'instant et les exécuter à la manière souhaitée.

Solution:

ce que vous devez faire est tout d’abord de rechercher la commande "dispatch_async" à l’origine de cet incident, puis d’utiliser une des autres files d’attente (c’est-à-dire attendre une réponse plus lente que celle attendue pour cette tâche),

généralement les développeurs ne pensent pas à cela et utilisent simplement la file principale qui est la priorité/file par défaut comme ceci:

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

afin de résoudre ce problème (si l'application vous informe que vous avez surchargé la file d'attente principale), vous devez la remplacer par l'une des autres files d'attente, comme ceci:

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

si vous n'avez pas besoin d'une exécution en arrière-plan (ou parallèle), vous pouvez même ignorer la commande dispatch_async et simplement exécuter vos commandes de la manière suivante:

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

Réécrivez la réponse de Shaybc dans Swift 3:

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

Pour Swift 3, utilisez:

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