🐙

Swift Concurrency⑤:Task.cancel(),Task.isCancelledとは?

に公開

Task.cancel()一言で言うと

"もうこのTaskいらないから、止めていいよ"
です。

キャンセルは「お願い」であって強制終了ではない

Task.cancel() を呼んでも すぐに止まるわけではありません。

タスクに「キャンセルフラグ」が立つだけ。

タスクの中で Task.isCancelled をチェックしたり、
try Task.checkCancellation() を呼ぶことで、ちゃんと止まる。

なぜキャンセルが必要?

iOS アプリでよくある場面👇

ユーザーが画面を閉じた

リストをスクロールして、前の API リクエスト結果はもう不要になった

ユーザーが操作をやり直した(古い処理を全部キャンセルしたい)

👉 こういうときに無駄な処理を走らせ続けると、電池やデータ通信を無駄遣いしてしまいます。

基本的な使い方

キャンセルされる側

func loadData() async {
    for i in 1...5 {
        // キャンセルされていたら止める
        if Task.isCancelled { 
            print("Task cancelled at step \(i)")
            return
        }

        print("Loading step \(i)")
        try? await Task.sleep(nanoseconds: 1_000_000_000) // 1秒
    }
    print("Finished loading")
}

キャンセルする側

let task = Task {
    await loadData()
}

// 2秒後にキャンセル
Task {
    try? await Task.sleep(nanoseconds: 2_000_000_000)
    task.cancel()
}

👉 実行すると

ステップ 1 → ステップ 2 までは動く

そのあとキャンセルされて Task.cancelled が true になる

途中で止まる

まとめ

Task.cancel() = 「このタスクもういらないよ」の合図

強制終了ではなく、キャンセルされる側が対応しないと止まらない

実務では「画面が消えた」「ユーザーが操作を変えた」ときによく使う

Discussion