Wie kann ich in Swift eine Funktion mit einem Completion-Handler erstellen?


116

Ich war nur neugierig, wie ich das angehen würde. Wenn ich eine Funktion hätte und wollte, dass etwas passiert, wenn sie vollständig ausgeführt wurde, wie würde ich dies der Funktion hinzufügen? Vielen Dank


2
Es gibt ein erstaunliches Video auf Youtube: google.com/…
Bright Future

Antworten:


174

Angenommen, Sie haben eine Download-Funktion zum Herunterladen einer Datei aus dem Netzwerk und möchten benachrichtigt werden, wenn die Download-Aufgabe abgeschlossen ist.

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

Ich hoffe es hilft.


2
Das würde großartig funktionieren, aber mehr aus Neugier fragte ich mich, ob Sie irgendwie einen Completion-Handler in Ihre Funktion schreiben könnten.
Traw1233

1
Hallo Floks, ich möchte diesen CompletionHandler von einer anderen Funktion aus aufrufen. Wie kann man das erreichen?
Himanshu Jamnani

irgendein Beispiel für Ziel c
Xcodian Solangi

Wenn ich es von einer anderen Klasse aufrufe, sät es keinen Erfolgsparameter für den Abschluss-Handler.
Chandni

84

Ich hatte Probleme, die Antworten zu verstehen, daher gehe ich davon aus, dass jeder andere Anfänger wie ich das gleiche Problem haben könnte wie ich.

Meine Lösung entspricht der Top-Antwort, ist aber hoffentlich etwas klarer und verständlicher für Anfänger oder Leute, die nur Probleme mit dem Verständnis im Allgemeinen haben.

So erstellen Sie eine Funktion mit einem Completion-Handler

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

     print("Doing something!")

     finished()

}

um die Funktion zu nutzen

     override func viewDidLoad() {

          yourFunctionName {

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

    }

Ihre Ausgabe wird sein

Etwas machen

Tada !!!

Hoffe das hilft!


80

Einfaches Swift 4.0-Beispiel:

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

Wie man es benutzt:

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

Zu diesem Zweck können wir Verschlüsse verwenden. Versuche Folgendes

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

Irgendwann können wir diese Funktion wie unten angegeben aufrufen.

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

Weitere Informationen zu Verschlüssen finden Sie unter folgendem Link .

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


5

Swift 5.0 +, einfach und kurz

Beispiel:

Stil 1

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

          print("block_Completion")
          completionBlock()
    }

Stil 2

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

        print("block_Completion")
        completionBlock()
    }

Verwenden:

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

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

Ausgabe

block_Completion

Nach Block_Completion etwas tun !!


0

Ich bin ein wenig verwirrt über maßgeschneiderte Fertigstellungshandler. In Ihrem Beispiel:

Angenommen, Sie haben eine Download-Funktion zum Herunterladen einer Datei aus dem Netzwerk und möchten benachrichtigt werden, wenn die Download-Aufgabe abgeschlossen ist.

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

Ihre // download code wird weiterhin asynchron ausgeführt. Warum geht der Code nicht direkt zu Ihnen let flag = trueund completion Handler(success: flag)ohne darauf zu warten, dass Ihr Download-Code fertig ist?


Irgendwann muss etwas sitzen und warten, bis der Code ausgeführt wird. Es ist kein riesiger Turm asynchroner Elefanten ganz unten. "Asynchron ausgeführt" bedeutet, dass zwei Threads vorhanden sind. Einer von ihnen sitzt und wartet auf die Aufgabe, der andere macht weiter und tut es nicht. Der Completion-Handler wird am Ende des Threads, der die Arbeit ausführt, aufgerufen oder soll zumindest aufgerufen werden.
Crowman

0

Zusätzlich zu oben: Der hintere Verschluss kann verwendet werden.

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

  // When download completes,control flow goes here.
  if success {
      // download success
  } else {
    // download fail
  }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.