2017-09-15 1 views
0

Mon objectif est d'effectuer une opération lourde en ressources de manière asynchrone et de m'assurer qu'elle est terminée avant de renvoyer les objets.Vérification de l'exécution de la boucle dans l'opération asynchrone avant de retourner

C'est la structure:

func modifyGadgets() -> [Gadget] { 

    var gadgetsToModify = [Gadget]() //this is already populated elsewhere 

    DispatchQueue.global(qos: .userInitiated).async { 
     //Do something to the original gadgets 
     for gadget in gadgetsToModify { 
      modifyThisGadget(gadget) 
     } 

     DispatchQueue.main.async { 
      return gadgetsToModify //I get a warning here saying gadgetsToModify is unused 
     } 

    } 
} 

En plus de l'avertissement, je aussi ne reçoivent aucune des Gadget articles de retour.

Comment est-ce que je devrais structurer ceci ainsi je suis capable de renvoyer les articles une fois qu'il est fini?

Merci.

Répondre

3

Pour cela, vous devez utiliser un gestionnaire d'achèvement .

func modifyGadgets(_ callback: @escaping ([Gadget]) ->()) { 
    var gadgetsToModify = [Gadget]() 

    DispatchQueue.global(qos: .userInitiated).async { 
     for gadget in gadgetsToModify { 
      modifyThisGadget(gadget) 
     } 

     DispatchQueue.main.async { 
      callback(gadgetsToModify) 
     } 
    } 
} 

Vous pouvez l'utiliser de cette façon:

modifyGadgets { gadgets in 
    print(gadgets) 
} 
+1

Vous avez besoin '@ escaping' sur le gestionnaire d'achèvement. –

+0

Merci à vous deux. C'est très utile – daspianist

2

Si l'opération est asynchrone, vous ne serez pas en mesure de retourner une valeur de cette façon. Qu'est-ce que vous voulez faire est au lieu de prendre une fermeture en tant que gestionnaire d'achèvement:

func modifyGadgets(completionHandler: @escaping ([Gadget]) ->()) { 
    let gadgets = ... 

    DispatchQueue.global(qos: .userInitiated).async { 
     //Do something to the original gadgets 
     for eachGadget in gadgets { 
      modifyThisGadget(eachGadget) 
     } 

     completionHandler(gadgets) 
    } 
} 

Ensuite, vous pouvez l'appeler comme ceci:

modifyGadgets { gadgets in 
    // do something with gadgets 
}