0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

コールバックを簡単におさらいする

Posted at

コールバックとは何か?

ある処理が完了するとか何かのイベントが発生する際に、処理の完了を通知したり別の処理を呼び出す仕組み。要は、complition()が通知された場所やタイミングでいろんなこと(処理)ができますよ〜みたいな。

  • その処理の完了の通知別の処理を呼び出す目印として、関数の引数が使われる。
    • ある関数に対して、引数をコールバックとして渡し、その関数内で引数(コールバック)を呼び出すみたいな感じ。
      • 画像でいうcomplition引数がコールバックと呼ばれるもの(度々目にするのでは?)
      • print文の後に処理が完了したことをコールバックを呼び出して通知している。
        スクリーンショット 2023-05-04 14.10.31.png

なぜコールバックを使うのか?(通常の関数と非同期処理を含む関数の違い’を添えて)

非同期処理を含む関数では、戻り値を返す前に別の処理が実行されることがあることや非同期なので戻り値を返すのに時間がかかる(ニュアンス的には前述と近いかも)ことがあり、それらのことを対策をしたいから。
asynchronous.png

  • 通常の関数の場合
Swift
//通常、関数は呼び出された後、順番に処理を行い、戻り値を受け取る。
//そして、関数を呼び出した場合、次に待っている処理に進んでいく。
func someFunction() -> String {
    //何か処理をする
    //・・・
    
    return "この文字列を戻り値に返すよ"
}

//関数の呼び出し
//これが終わったら次の処理へ進む
someFunction()
  • 非同期処理を含む関数の場合
Swift
//一方、非同期処理を含む関数では、「戻り値を返す前に別の処理が実行されることがある」ことや「非同期なので戻り値を返すのに時間がかかる」ことがある。
//非同期処理の画像
//そのため、非同期処理を含む関数では、「戻り値を受け取る前に呼び出し元の関数が終了する」(場合がある)。
//それを避けたいため、非同期処理が成功が完了したこと、失敗が完了したこと、それらの処理の完了をコールバックとして引数に渡されたクロージャーを使う。
func fetchData(completion: @escaping (Result<Data, Error>) -> Void) {
    let url = URL(string: "https://example.com/api/data")!
    let task = URLSession.shared.dataTask(with: url) { data, response, error in
        if let error = error {
            //失敗が完了したことの通知
            completion(.failure(error))
            return
        }
        guard let data = data else {
            let error = NSError(domain: "com.example", code: 0, userInfo: [NSLocalizedDescriptionKey: "Data is nil."])
            //失敗が完了したことの通知
            completion(.failure(error))
            return
        }
        //成功が完了したの通知
        completion(.success(data))
    }
    task.resume()
}

//最後にコールバック関数を呼び出して、非同期処理が完了した結果(成功したとき、失敗したとき)を受け取り、各々(成功したとき、失敗したとき)の処理を定義している。
fetchData { result in
    switch result {
    case .success(let data):
        print("Data received: \(data)")
    case .failure(let error):
        print("Error: \(error)")
    }
}

おわりに

何かご指摘等ございましたらコメ欄までお願いします。

参考記事

株式会社アールワークス:非同期処理の画像

[増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plusシリーズ) 
↑引用元
石川 洋資 (著), 西山 勇世 (著)
発行者:片岡 巌
出版社:技術評論社
印刷/製本:日経印刷株式会社

開発環境

  • Xcode-13.4.1
  • Swift version 5.7
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?