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

chalut1233
la source
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.

tounaobun
la source
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!

Cyril
la source
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")
    }
})
Policier
la source
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

arango_86
la source
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 !!

Lakhdeep Singh
la source
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é?

Respiration lourde
la source
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
  }
}
Shrawan
la source