Jak mogę utworzyć funkcję z programem obsługi zakończenia w Swift?


Odpowiedzi:


174

Załóżmy, że masz funkcję pobierania umożliwiającą pobranie pliku z sieci i chcesz otrzymać powiadomienie o zakończeniu zadania pobierania.

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

Mam nadzieję, że to pomoże.


2
To by działało świetnie, ale bardziej z ciekawości, zastanawiałem się, czy możesz w jakiś sposób napisać procedurę obsługi uzupełniania do swojej funkcji.
traw1233

1
Cześć Floks, chcę nazwać to CompletionHandler z innej funkcji, więc jak to osiągnąć?
Himanshu jamnani

dowolny przykład dla celu c
Xcodian Solangi

Kiedy wywołuję to przez inną klasę, nie wysiewa parametru sukcesu obsługi zakończenia.
Chandni,

85

Miałem problemy ze zrozumieniem odpowiedzi, więc zakładam, że każdy inny początkujący, taki jak ja, może mieć ten sam problem co ja.

Moje rozwiązanie działa tak samo jak najlepsza odpowiedź, ale mam nadzieję, że jest trochę jaśniejsze i łatwiejsze do zrozumienia dla początkujących lub osób mających problemy ze zrozumieniem.

Aby utworzyć funkcję z obsługą zakończenia

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

     print("Doing something!")

     finished()

}

użyć funkcji

     override func viewDidLoad() {

          yourFunctionName {

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

    }

Twoje wyjście będzie

Robić coś

Tada !!!

Mam nadzieję że to pomoże!


80

Prosty przykład 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)
}

Jak tego użyć:

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

W tym celu możemy użyć Zamknięcia . Spróbuj wykonać następujące czynności

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

W pewnym momencie możemy wywołać tę funkcję, jak podano poniżej.

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

Więcej informacji na temat zamknięć można znaleźć pod poniższym linkiem .

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


5

Swift 5.0 +, prosty i krótki

przykład:

Styl 1

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

          print("block_Completion")
          completionBlock()
    }

Styl 2

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

        print("block_Completion")
        completionBlock()
    }

Posługiwać się:

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

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

Wynik

block_Completion

Robię coś po Block_Completion !!


0

Jestem trochę zdezorientowany co do niestandardowych programów obsługi zakończenia. W twoim przykładzie:

Załóżmy, że masz funkcję pobierania umożliwiającą pobranie pliku z sieci i chcesz otrzymać powiadomienie o zakończeniu zadania pobierania.

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

Twój // download codebędzie nadal uruchamiany asynchronicznie. Dlaczego kod nie trafiłby prosto do Ciebie let flag = truei completion Handler(success: flag)nie czekałby na zakończenie pobierania?


W końcu coś musi siedzieć i czekać na uruchomienie kodu, nie jest to gigantyczna wieża asynchronicznych słoni na samym dole. „Uruchomiony asynchronicznie” oznacza, że ​​istnieją dwa wątki. Jeden z nich siedzi i czeka na wykonanie zadania, drugi kontynuuje i nie robi. Procedura obsługi zakończenia jest wywoływana lub przynajmniej planowana do wywołania na końcu wątku, który wykonuje pracę.
Crowman,

0

Oprócz powyższego: można zastosować zamknięcie końcowe .

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

  // When download completes,control flow goes here.
  if success {
      // download success
  } else {
    // download fail
  }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.