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

116

Byłem po prostu ciekawy, jak podejdę do tego. Gdybym miał funkcję i chciałbym, żeby coś się wydarzyło po jej całkowitym wykonaniu, jak dodałbym to do funkcji? Dzięki

traw1233
źródło
2
Na Youtube jest niesamowity film: google.com/…
Bright Future

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.

tounaobun
źródło
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!

Cyryla
źródło
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")
    }
})
Konstabl
źródło
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

arango_86
źródło
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 !!

Lakhdeep Singh
źródło
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?

Ciężki oddech
źródło
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
  }
}
Shrawan
źródło