Swift에서 완료 핸들러로 함수를 어떻게 만들 수 있습니까?


116

나는 이것에 어떻게 접근할지 궁금했습니다. 함수가 있고 그것이 완전히 실행되었을 때 어떤 일이 일어나기를 원했다면 어떻게 이것을 함수에 추가할까요? 감사


2
Youtube에 놀라운 동영상이 있습니다. google.com/…
Bright Future

답변:


174

네트워크에서 파일을 다운로드하는 다운로드 기능이 있고 다운로드 작업이 완료되면 알림을 받고 싶다고 가정 해 보겠습니다.

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

도움이 되었기를 바랍니다.


2
이것은 훌륭하게 작동하지만 호기심에서 더 많이 함수에 완료 핸들러를 작성할 수 있는지 궁금합니다.
traw1233

1
안녕하세요 Floks, 다른 함수 에서이 CompletionHandler를 호출하고 싶습니다.
Himanshu jamnani

대물 C에 대한 예
Xcodian Solangi

다른 클래스에서 호출하면 완료 핸들러 성공 매개 변수를 파종하지 않습니다.
CHANDNI

85

답을 이해하는 데 어려움이있어서 저와 같은 다른 초보자도 저와 같은 문제가있을 수 있다고 가정합니다.

내 솔루션은 최상위 답변과 동일하지만 초보자 또는 일반적으로 이해하기 어려운 사람들에게 조금 더 명확하고 이해하기 쉽기를 바랍니다.

완료 처리기를 사용하여 함수를 만들려면

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

     print("Doing something!")

     finished()

}

기능을 사용하려면

     override func viewDidLoad() {

          yourFunctionName {

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

    }

당신의 출력은

뭔가를하고

타다 !!!

도움이 되었기를 바랍니다!


80

간단한 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)
}

사용 방법:

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

이러한 목적으로 클로저 를 사용할 수 있습니다 . 다음을 시도하십시오

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

어떤 시점에서 우리는이 함수를 아래와 같이 호출 할 수 있습니다.

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

폐쇄에 대한 자세한 내용은 다음 링크를 참조하십시오 .

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


5

Swift 5.0 +, 간단하고 짧음

예:

스타일 1

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

          print("block_Completion")
          completionBlock()
    }

스타일 2

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

        print("block_Completion")
        completionBlock()
    }

사용하다:

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

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

산출

block_Completion

Block_Completion 이후에 뭔가 해요 !!


0

맞춤 제작 완료 핸들러에 대해 약간 혼란 스럽습니다. 귀하의 예에서 :

네트워크에서 파일을 다운로드하는 다운로드 기능이 있고 다운로드 작업이 완료되면 알림을 받고 싶다고 가정 해 보겠습니다.

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

귀하는 // download code여전히 비동기 적으로 실행됩니다. 왜 코드는 바로 갈 것입니다 let flag = truecompletion Handler(success: flag)완료 할 다운로드 코드를 기다리지 않고?


결국, 무언가가 앉아서 코드가 실행될 때까지 기다려야합니다. 그것은 끝까지 내려 오는 거대한 비동기 코끼리 타워가 아닙니다. "Ran asynchronously"는 두 개의 스레드가 있음을 의미합니다. 그들 중 하나는 앉아서 작업이 완료되기를 기다리고, 다른 하나는 계속해서 수행하지 않습니다. 완료 핸들러는 작업을 수행하는 스레드의 끝에서 호출되거나 적어도 호출되도록 예약됩니다.
Crowman

0

위에 추가 : 후행 폐쇄를 사용할 수 있습니다.

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

  // When download completes,control flow goes here.
  if success {
      // download success
  } else {
    // download fail
  }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.