Meet async/await in Swift集まれSwift好き!Swift愛好会スピンオフWWDC21セッション要約会 @オンライン2021/06/25 Hironobu Iga
View Slide
自己紹介● Hironobu Iga● Flutter, React, Ktor(Kotlin), iOS● Twitter - @iganin_dev
同期処理と非同期処理
非同期処理非同期処理を活用することでスレッドを有効に使える(通信、DB etc)
非同期処理非同期処理を活用することでスレッドを有効に使える(通信、DB etc)同期処理はスレッドをブロックする
非同期処理非同期処理を活用することでスレッドを有効に使える(通信、DB etc)非同期処理によって処理の待ち時間に他の処理を差し込むことができる
非同期処理の例
サムネイル画像を取得する
同期処理
非同期処理
従来のCompletion Handlerを使用した方法
ネストが深い
エラーハンドリングを completionで伝える必要がある漏れていてもコンパイラが検知してくれない同様に値の返却も忘れる可能性があり、こちらもコンパイラが検知してくれない
実行順が複雑で処理を追うのが難しい
async / await を使った方法
内部で中断する処理が入る場合はasyncをつける例外を投げる場合は、async throwsの順でないとコンパイルエラー※SE-0296に詳細
中断する処理には await をつける例外を投げる可能性がある場合は try await※ await try はコンパイルエラー
例外が発生しうる処理は try await と記載され、例外処理の実装漏れの可能性がなくなったcompletionの書き漏れによる値の返却漏れもなくなった
実行順が上から下になり、処理が格段に追いやすくなった
getter ( setter は不可 ) - SE-0310, for 文init( deinit は不可 ), subscript ( arrray[i]のようなアクセス)async / await が使用できるケース
上記は await の関数を直列に順次実行していく同時に並列に実行する方法は、Structured concurrency in Swift セッション で確認可能
async / await になったメソッドをSwiftUIで使う
async / await になったメソッドをSwiftUIで使う中断をする関数をawait付きで呼び出すために async { } で囲う必要がある
● URLSession● MapKit● HealthKit● NSDocument● etc...asnyc / await はさまざまなSDKに導入済み
Continuation
Continuation● 中断している処理を保持し、処理の再開(resume)を明示的に行える○ 実装を見ているとCompletion Handlerに似てる気がする● 再開(resume)は一度しか呼べない● withCheckedContinuation○ 呼び出しが一度だけかどうか、呼び出し忘れていないかどうかを実行時にチェックしてくれる○ 2度呼び出した場合はクラッシュ (CONTINUATION MISUSE)● withUnsafeContinuation○ 呼び出しが一度だけか、呼び出し忘れがないかのチェックがない○ 2度呼び出した場合はクラッシュ (EXC_BAD_ACCESS)○ SDKなどでのパフォーマンス効率化以外では極力使用しない
Continuationを使う例以下の処理を考える● PeerManagerの syncSharedPostメソッドを呼び出す● 返却値かエラーをDelegateメソッドを介して受け取る上記ををasync / await を使用した形に書き換える
メソッド呼び出しの結果を delegateメソッド経由で受け取る
メソッド呼び出しに関する Continuationをクラスのプロパティに保持する (CompletionHandlerを保持するのと似てる )
Delegateメソッドに値が返ってきたタイミングで結果とともにcontinuationのrsumeを呼ぶcontinuationは1度しかresumeできないため保持していたcontinuationは破棄する
まとめ● async / await で非同期処理がシンプルにかける● getter, for文 initializer, subscript etcで使える● completionHandler の async / await への置き換え● Delegationメソッドのasync / awaitへの置き換え● 複数のSDKにすでに導入済み● Continuationについて● セッションにはなかったですが、 iOS15以上でないと使用できないようです