2016-11-17 1 views
2

Dans mon exemple de code ci-dessous, j'appelle complete(false) en cas d'échec. Cependant, depuis que je suis sur un objet DispatchGroup pour vous assurer que toutes les requêtes asynchrones soient terminées, je ne peux pas appeler syncGroup.leave() en cas d'échec, comme notify sera appelée, qui contient complete(true), ce qui en retour de la fonction true, quand il devrait être de retour false pour l'échec.Comment utiliser DispatchGroup pour effectuer des appels asynchrones dans une boucle for

Ai-je raison de ne pas appeler syncGroup.leave() si la fonction n'a pas été exécutée correctement? Ou devrais-je appeler syncGroup.leave() et d'une certaine manière en essayant de déterminer ce que le résultat est, afin que je puisse retourner false en cas d'échec?

let syncGroup = DispatchGroup() 
syncGroup.enter() 
for track in unsynced { 
    register(time: time, withCompletion: { (success: Bool) ->() in 

     if success { 
      self.debug.log(tag: "SyncController", content: "Registered") 
      syncGroup.leave() 
     } 
     else { 
      complete(false) 
     } 
    }) 
} 

//all requests complete 
syncGroup.notify(queue: .main) { 
    self.debug.log(tag: "SyncController", content: "Finished registering") 
    complete(true) 
} 
+0

Votre approche est erronée puisque vous dispatching de nombreuses tâches, mais seulement le retour d'un statut unique. Vous devez considérer ce que vous voulez accomplir; Vous devriez peut-être être prêt à recevoir plusieurs rappels (en passant peut-être le 'track' ainsi que le résultat true/false) ou appeler le callback une fois mais passer un tableau de pistes/statuts – Paulw11

Répondre

2

Vous devez entrer le groupe dans votre boucle for. Vous pourriez vouloir introduire un drapeau d'erreur supplémentaire.

mise en œuvre Exemple:

var fail = false 
    let syncGroup = DispatchGroup() 

    for track in unsynced { 
     syncGroup.enter() 
     register(time: time, withCompletion: { (success: Bool) ->() in 

      if success { 
       self.debug.log(tag: "SyncController", content: "Registered") 
       syncGroup.leave() 
      } 
      else { 
       fail = true 
       syncGroup.leave() 
      } 
     }) 
    } 

    //all requests complete 
    syncGroup.notify(queue: .main) { 
     if fail { 
      complete(false) 

     } else { 
      self.debug.log(tag: "SyncController", content: "Finished registering") 
      complete(true) 
     } 
    } 
+0

Comment puis-je quitter cette boucle de passer à travers les objets restants dans 'unsynced'? 'break' ne fonctionnera pas parce que c'est dans une fermeture droite? – toast

+0

Vous ne pouvez pas. La boucle déclenche vos opérations asynchrones. Très probablement (selon l'heure d'utilisation de la tâche et le nombre de 'unsynced') toutes les tâches de registre sont déclenchées avant que le premier ne l'appelle bloc d'achèvement. Pour beaucoup d'éléments dans 'unsynced', vous pouvez ajouter' if fail {break }' comme premier code dans la 'boucle for '. – shallowThought

+0

Ah ok, merci. Bien que ces demandes soient asynchrones, il est possible que vous en sauviez une ou deux en envoyant une requête. – toast