Comment créer une fonction avec un gestionnaire de complétion dans Swift?


117

J'étais juste curieux de savoir comment j'aborderais cela. Si j'avais une fonction et que je voulais que quelque chose se produise lorsqu'elle était entièrement exécutée, comment l'ajouterais-je à la fonction? Merci


2
Il y a une vidéo incroyable sur Youtube: google.com/...
Bright Future

Réponses:


174

Supposons que vous disposiez d'une fonction de téléchargement pour télécharger un fichier à partir du réseau et que vous souhaitiez être averti lorsque la tâche de téléchargement est terminée.

typealias CompletionHandler = (success:Bool) -> Void

func downloadFileFromURL(url: NSURL,completionHandler: CompletionHandler) {

    // download code.

    let flag = true // true if download succeed,false otherwise

    completionHandler(success: flag)
}

// How to use it.

downloadFileFromURL(NSURL(string: "url_str")!, { (success) -> Void in

    // When download completes,control flow goes here.
    if success {
        // download success
    } else {
        // download fail
    }
})

J'espère que ça aide.


2
Cela fonctionnerait très bien, mais plus par curiosité, je me demandais si vous pouviez en quelque sorte écrire un gestionnaire de complétion dans votre fonction.
traw1233

1
Salut Floks, je veux appeler ce CompletionHandler à partir d'une autre fonction, alors comment y parvenir?
Himanshu jamnani

n'importe quel exemple pour l'objectif c
Xcodian Solangi

Quand je l'appelle par une autre classe, il ne sème pas le paramètre de succès du gestionnaire d'achèvement.
Chandni

86

J'ai eu du mal à comprendre les réponses, donc je suppose que tout autre débutant comme moi pourrait avoir le même problème que moi.

Ma solution fait la même chose que la réponse principale mais, espérons-le, un peu plus claire et facile à comprendre pour les débutants ou les personnes ayant simplement du mal à comprendre en général.

Pour créer une fonction avec un gestionnaire de complétion

func yourFunctionName(finished: () -> Void) {

     print("Doing something!")

     finished()

}

pour utiliser la fonction

     override func viewDidLoad() {

          yourFunctionName {

          //do something here after running your function
           print("Tada!!!!")
          }

    }

Votre sortie sera

Faire quelque chose

Tada !!!

J'espère que cela t'aides!


80

Exemple simple de Swift 4.0:

func method(arg: Bool, completion: (Bool) -> ()) {
    print("First line of code executed")
    // do stuff here to determine what you want to "send back".
    // we are just sending the Boolean value that was sent in "back"
    completion(arg)
}

Comment l'utiliser:

method(arg: true, completion: { (success) -> Void in
    print("Second line of code executed")
    if success { // this will be equal to whatever value is set in this method call
          print("true")
    } else {
         print("false")
    }
})

12

Nous pouvons utiliser des fermetures à cette fin. Essayez ce qui suit

func loadHealthCareList(completionClosure: (indexes: NSMutableArray)-> ()) {
      //some code here
      completionClosure(indexes: list)
}

À un moment donné, nous pouvons appeler cette fonction comme indiqué ci-dessous.

healthIndexManager.loadHealthCareList { (indexes) -> () in
            print(indexes)
}

Veuillez consulter le lien suivant pour plus d'informations concernant les fermetures .

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html


5

Swift 5.0 +, simple et court

exemple:

Style 1

    func methodName(completionBlock: () -> Void)  {

          print("block_Completion")
          completionBlock()
    }

Style 2

    func methodName(completionBlock: () -> ())  {

        print("block_Completion")
        completionBlock()
    }

Utilisation:

    override func viewDidLoad() {
        super.viewDidLoad()
        
        methodName {

            print("Doing something after Block_Completion!!")
        }
    }

Production

block_Completion

Faire quelque chose après Block_Completion !!


0

Je suis un peu confus à propos des gestionnaires de complétion personnalisés. Dans votre exemple:

Supposons que vous disposiez d'une fonction de téléchargement pour télécharger un fichier à partir du réseau et que vous souhaitiez être averti lorsque la tâche de téléchargement est terminée.

typealias CompletionHandler = (success:Bool) -> Void

func downloadFileFromURL(url: NSURL,completionHandler: CompletionHandler) {

    // download code.

    let flag = true // true if download succeed,false otherwise

    completionHandler(success: flag)
}

Votre // download codesera toujours exécuté de manière asynchrone. Pourquoi le code n'irait-il pas directement dans votre let flag = trueet completion Handler(success: flag)sans attendre que votre code de téléchargement soit terminé?


Finalement, quelque chose doit s'asseoir et attendre que le code s'exécute, ce n'est pas une tour géante d'éléphants asynchrones tout en bas. «Ran asynchronously» signifie qu'il y a deux threads. L'un d'eux s'assoit et attend que la tâche soit accomplie, l'autre continue et non. Le gestionnaire d'achèvement est appelé, ou du moins planifié pour être appelé, à la fin du thread qui effectue le travail.
Crowman

0

En plus de ce qui précède: la fermeture arrière peut être utilisée.

downloadFileFromURL(NSURL(string: "url_str")!)  { (success) -> Void in

  // When download completes,control flow goes here.
  if success {
      // download success
  } else {
    // download fail
  }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.