1. HOME
  2. ブログ
  3. IT技術
  4. 【iOS】Swift Concurrencyに入門してみた

【iOS】Swift Concurrencyに入門してみた

はじめに

Swift Concurrencyを勉強したので、備忘録を残しておこうと思います

Swift Concurrency

Swift Concurrencyとは、Swift5.5から導入された言語機能で非同期処理と並列処理の実装をサポートします

async/await

関数のreturn矢印の前にasyncをつけることで非同期関数として扱えるようになり、
awaitをつけて呼び出すことで処理が終わるまで実行が一時停止します

以下はコールバック処理で書いた場合とそれをasync/awaitに書き換えた場合の例です

比較してみると、コールバックではネストする必要がありますが、async/awaitでは同期的にコードを書けていることが分かります

エラーが発生する非同期関数では、throwsの前にasyncをつけることで非同期関数にします
呼び出し時には、通常と同じようにtryをつけて呼び出します

async let

async letを使うことで非同期関数を並列に実行することができます

コールバック関数を非同期関数へ変換

withCheckedContinuationを使うことで既存のコールバック関数を非同期関数へ変換することができます
エラーが発生するコールバック関数の場合は、withCheckedThrowingContinuationを使用します

Task

タスクは非同期処理の実行単位です
Taskを使うことで同期関数から非同期関数を呼び出すことができるようになります

Task.initは現在の実行環境を引き継ぎます
@MainActorでTask.initを使った場合、タスクは@MainActorで実行されます

Task.detachedは現在の実行環境を引き継ぎません
メインスレッドで実行する必要がないものはTask.detachedを使用します

Taskのインスタンスを保持することでタスクをキャンセルすることができます
以下のコードでは、タスクをキャンセルすることでworld()が実行されずにエラーが発生して終了します

TaskGroup

TaskGroupを使うことで並列処理を実装することができます
TaskGroupの作成にはwithTaskGroupを使用します
エラーが発生する場合はwithThrowingTaskGroupを使用します

以下のコードではhello()とworld()が並列に実行され、"HelloWorld"または"WorldHello"で出力されます

タスクのキャンセル

CancellationErrorをスローすることでタスクをキャンセルできます
タスクがキャンセルされている場合、Task.checkCancellationではCancellationErrorがスローされます
また、Task.isCancelledでタスクがキャンセルされているか判定することもできます

actor

actorはデータ競合を防ぐ型でclassと同じ参照型です
プロパティ、メソッド、イニシャライザの定義とプロトコル準拠ができますが、actorの型を継承することはできません
プロパティやメソッドを使う時にawaitをつけることでデータ競合を防ぐ仕組みがあります
actorのプロパティは外から直接更新することはできません
nonisolatedをつけることでactor管理から外れ、awaitなしでアクセスできるようになります

@MainActor

@MainActorに適応したものはメインスレッドで実行されます
nonisolatedをつけることでMainActor管理から外れ、awaitなしでアクセスできるようになります
型、コンピューテッドプロパティ、メソッドに@MainActor属性を付けることができますが、ストアドプロパティーに@MainActorを適応することはできません

Async Sequence

Async Sequenceは要素への非同期、順次、反復アクセスを提供する型で、filter、contains、mapなどのメソッドが標準で用意されています
AsyncSequenceとAsyncIteratorProtocolに準拠することで独自の型を作成することができます

Sendable

Sendableはデータ競合を防ぐための型です
actorは参照型ですが、同時アクセスを防ぐためSendableといえます
外からactor内のメソッドを呼び出す場合には、引数はSendableな値である必要があります
@Sendableをメソッド、クロージャにつけることで、Sendableとして扱うことができます
structとenumはSendableな値(プロパティ、メソッドなど)のみを持つ場合、暗黙的にSendableに準拠されます(publicな型の場合は例外)

おわりに

今回、Swift Concurrencyの書き方をまとめてみました。
Swift Concurrencyを使用する時には、この記事を見返しながら実装をしたいと思います。

この記事が何かお役に立てば幸いです。
ここまでご覧いただきありがとうございました。

書いた人はこんな人

いまむー(エンジニア)
いまむー(エンジニア)
業務ではiOS開発に携わらせていただいています。
まだまだ分からないことだらけで、日々分からないことと戦いながら仕事をしている者です。
ブログ記事は暖かい目で見ていただけるとありがたいです。

関連記事

採用情報

\ あの有名サービスに参画!? /

バックエンドエンジニア

\ クリエイティブの最前線 /

フロントエンドエンジニア

\ 世界を変える…! /

Androidエンジニア

\ みんなが使うアプリを創る /

iOSエンジニア