web-dev-qa-db-ja.com

Swiftで完了ハンドラを使用して関数を作成するにはどうすればよいですか?

私はこれにどうアプローチするかについて興味がありました。関数があり、それが完全に実行されたときに何かを実行したい場合、これを関数にどのように追加しますか?ありがとう

97
traw1233

ネットワークからファイルをダウンロードするダウンロード機能があり、ダウンロードタスクが完了したときに通知を受け取る必要があるとします。

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

それが役に立てば幸い。 :-]

145
tounaobun

単純な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")
    }
})
66
Bobby

私は答えを理解するのに苦労したので、私のような他の初心者も私と同じ問題を抱えていると思います。

私のソリューションはトップアンサーと同じことをしますが、初心者や一般的な理解に苦労している人にとっては、もう少し明確で理解しやすいことを願っています。

完了ハンドラーを使用して関数を作成するには

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

     print("Doing something!")

     finished()

}

機能を使用するには

     override func viewDidLoad() {

          yourFunctionName {

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

    }

あなたの出力は

Doing something
Tada!!!

お役に立てれば!

60

この目的のためにClosuresを使用できます。以下を試してください

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

ある時点で、次のようにこの関数を呼び出すことができます。

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

Closuresに関する詳細については、次のリンクを参照してください。

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

11
arango_86

私は、カスタムメイドの完了ハンドラーについて少し混乱しています。あなたの例では:

ネットワークからファイルをダウンロードするダウンロード機能があり、ダウンロードタスクが完了したときに通知を受け取る必要があるとします。

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)に直接移動しないのはなぜですか?

1
Heavy Breathing

上記に加えて:トレーリングクロージャを使用できます。

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

  // When download completes,control flow goes here.
  if success {
      // download success
  } else {
    // download fail
  }
}
0
Shrawan