Swift5.5で登場したasync/awaitを試してみました。
async/awaitは非同期処理を簡単に書けるような機能で通信処理などの実装を書きやすくなります。
今までは通信などの非同期処理を実装する時、下のように完了後のメソッド(completion)を使って実装する事が主流でした。
func asyncMethod(completion: () -> ()) { // 通信などの非同期処理 completion() } asyncMethod(completion: { // 完了後の処理 })
async/awaitを使って書き直すと下のようになります。
完了後の処理がcompletionではなくasyncMethodのすぐ下に書けるようになりました。
func asyncMethod() async { // 通信などの非同期処理 } Task { await self.asyncMethod() // 完了後の処理 }
下のようにasyncMethodの戻り値を受け取る事もできます。
func asyncMethod() async -> String { return "OK" } Task { let result = await self.asyncMethod() print(result) }
実行されるスレッドですが、Task内は元のスレッドとは別スレッドで実行されます。
具体的には下のようになります。
Task内のawaitまでの処理は同じスレッドで行われるという記述もあったのですが、検証したときは別スレッドになっていました。
この辺りは機会あれば詳しく調べてみようと思います。
func asyncMethod() async { print("asyncMethod: \(Thread.isMainThread)") // → false } print("1: \(Thread.isMainThread)") // → true Task { print("2: \(Thread.isMainThread)") // → false await self.asyncMethod() print("3: \(Thread.isMainThread)") // → false }
クラスに@MainActorを付けることでasyncのメソッドをメインスレッドで実行する事も可能です。
@MainActor class Test { func test() { print("1: \(Thread.isMainThread)") // → true Task { print("2: \(Thread.isMainThread)") // → false await self.asyncMethod() print("3: \(Thread.isMainThread)") // → true } } func asyncMethod() async { print("asyncMethod: \(Thread.isMainThread)") // → true } }