Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Swift Concurrency入門
Search
Sato Takeshi
February 22, 2022
Technology
10
4.8k
Swift Concurrency入門
集まれSwift好き!Swift愛好会 vol.65 @ オンライン
https://love-swift.connpass.com/event/238725/
発表資料
Sato Takeshi
February 22, 2022
Tweet
Share
More Decks by Sato Takeshi
See All by Sato Takeshi
Swift愛好会 の 思い出
satotakeshi
0
66
Xcode 15, Swift 5.9で変わる開発体験
satotakeshi
3
2.8k
Meet passkeys
satotakeshi
2
320
What's new in Vision
satotakeshi
0
1.4k
複数端末のつらさを乗り越えてiOS UITestを実行
satotakeshi
1
360
Xcodegenを個人アプリに導入
satotakeshi
3
710
SwiftUIで作る開閉式メニュー
satotakeshi
2
2.9k
swift-snapshot-testingでVisual Testingを効率化
satotakeshi
0
1.1k
SwiftUIのデータ管理
satotakeshi
7
1.8k
Other Decks in Technology
See All in Technology
Snowflake女子会#3 Snowpipeの良さを5分で語るよ
lana2548
0
220
GitHub Copilot のテクニック集/GitHub Copilot Techniques
rayuron
23
11k
Snykで始めるセキュリティ担当者とSREと開発者が楽になる脆弱性対応 / Getting started with Snyk Vulnerability Response
yamaguchitk333
2
180
Wvlet: A New Flow-Style Query Language For Functional Data Modeling and Interactive Data Analysis - Trino Summit 2024
xerial
1
110
CustomCopを使ってMongoidのコーディングルールを整えてみた
jinoketani
0
220
DevOps視点でAWS re:invent2024の新サービス・アプデを振り返ってみた
oshanqq
0
180
MLOps の現場から
asei
6
630
宇宙ベンチャーにおける最近の情シス取り組みについて
axelmizu
0
110
re:Invent をおうちで楽しんでみた ~CloudWatch のオブザーバビリティ機能がスゴい!/ Enjoyed AWS re:Invent from Home and CloudWatch Observability Feature is Amazing!
yuj1osm
0
120
AI時代のデータセンターネットワーク
lycorptech_jp
PRO
1
280
生成AIのガバナンスの全体像と現実解
fnifni
1
180
私なりのAIのご紹介 [2024年版]
qt_luigi
1
120
Featured
See All Featured
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
4 Signs Your Business is Dying
shpigford
181
21k
Practical Orchestrator
shlominoach
186
10k
Building Your Own Lightsaber
phodgson
103
6.1k
Unsuck your backbone
ammeep
669
57k
[RailsConf 2023] Rails as a piece of cake
palkan
53
5k
KATA
mclloyd
29
14k
The Cult of Friendly URLs
andyhume
78
6.1k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
26
1.5k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
170
Designing on Purpose - Digital PM Summit 2013
jponch
116
7k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
29
2k
Transcript
Swift Concurrency 入門 2022 年 2 月 22 日 集まれ
Swift 好き! Swift 愛好会 vol.65 @ オンライン
Who am I • Name • 佐藤タケシ ( さとうたけし )
• Company • Merpay, Inc.(2019/01 ~) • Role • Software Engineer (iOS) • Account • Twitter: @hatakenokakashi • Facebook: 佐藤剛士 • GitHub: SatoTakeshiX
• 一冊で Swift Concurrency の概 要を理解ことを目指して書いて います • まだ執筆中 •
Swift Concurrency は新しい概 念が盛りだくさん • 覚えればあなたの開発がより安 全に、簡単に実装できるように なる 「Swift Concurrency入門」で技術 書典で販売予定
Swift Concurrency • Swift 5.5 から導入 • Xcode 13 から利用可能
• 非同期処理が簡潔、安全に • async/await が Swift にやってき た!
コールバックによる 非同期処理の 欠点
ネストが深くなる
コールバックの呼び忘れ
コールバックの呼び忘れ コールバックを呼ばないで returnしている
呼び出し元で不具合発生 コールバックが呼ばれないので、 エラーが起きているのに、 ローディングビューがずっと出しっぱな しになるかもしれない
async/awaitで解決
async/awaitで非同期処理 • async で非同期関数を定義
async/awaitで非同期処理 • 呼び出し元
非同期関数 • async がつけられた関数・メソッド • プログラムを待機、再開させる • 通常のコードと同じように記述ができる ◦ 呼び出し元で、変数の代入や
try-catch によるエラーハンドリング ◦ 戻り値を定義できるのでコールバックのよう呼び忘れがない。コンパイルの チェックが入る • スレッドは CPU のコア数分用意される ◦ システムが管理し、開発者が直接触ることはない
awaitでプログラムが待機する
awaitでプログラムが待機する
awaitでプログラムが待機する
順次実行の実装の違い
順次実行をする by 同期関数 ネストが深くなる
順次実行をする by 非同期関数
並列実行の実装の違い
並列実行をする by 同期関数
並列実行をする by 非同期関数
データ競合を防ぐ新しい型 Actor
データ競合(Data Race)とは? • 複数のスレッドがデータに同時にアクセスしたためにデータが不正になる状況 ◦ スレッドの少なくとも一つが値を書き込む 値 スレッド 1 スレッド
2
データ競合(Data Race)
データ競合(Data Race) playgroundで実行すると 110,110が出力される場合がある
actorの特徴 • 新しい型の種類 • 参照型 • インスタンスに外からアクセスは同時にひとつのみに限定される ◦ Actor 隔離(
Actor isolated) と呼ぶ ◦ data race を防ぐ • 外からアクセスする場合は await が必要 • イニシャライザー、プロパティ、メソッド定義、プロトコル適応など class, struct, enum を同じ特徴をもつ
actorでデータ競合を防ぐ
actorでデータ競合を防ぐ 必ず100, 110が順不同で出力される -> データ競合がなくなる
actorで競合状態(Race Condition)は防げない • 競合状態 (Race Condition) マルチスレッドにおける典型的な不具合の一つ • プログラミングの実行結果が各スレッドの実行順に依存する状態 ◦
同じ入力を与えても異なるデータを出力する状態
actorで競合状態(Race Condition)は防げない
actorで競合状態(Race Condition)は防げない
actorで競合状態(Race Condition)は防げない 1. ③、④が同時に呼び出す 2. キャッシュはまだない 3. ③が①に到達。待機 4. ④が①に到達。待機
5. ③が再開。👾を返す。 6. ③が②に到達。 return する 7. ④が再開。🎃を返す。 8. ④が②に到達。 return する 9. ③、④同じ URL なのに違うコ ンテンツが返される=>競合 状態
競合状態(Race Condition)の修正 • await の後でプロパティの チェックする • Protect mutable state
with Swift actorsに Task を使った例もあり
MainActor • メインスレッドで実行される特別な Actor • Global Actor の一種 ◦ むしろメインスレッドのために
Global Actor が提案された ◦ 共有の actor インスタンスを通して Actor 分離がされる • @MainActor で型全部、プロパティのみ、メソッドのみなど適応できる
MainActorの適応方法 • MainActor の適応手順をコードで示す
Task
Task • 並行処理の基本単位。すべての非同期関数は Task を通して実行される • 各 Task を Task
Tree とよばれる親子関係を構築する • Task Tree のおかげでキャンセルや優先度をシンプルにハンドリング可能 ◦ 従来の方法だとあるスレッドの処理がキャンセルされた場合に他のスレッドの処 理に伝播させるのが難しかった
Task Tree • ①一番下位のタ スクがすべて終わ ると上位のタスク が始まる • ②子タスクが終わ ると親タスクに伝
播 • ③親タスクが実行
Task Tree • ①がエラー -> 兄弟 タスクはキャンセ ル② • 上位のタスク③が
キャンセル。兄弟 タスク④もキャン セル • ④の下位タスク⑤ もキャンセル • ⑥親タスクに①の エラー伝播
async letバインディングとTask Tree
async letバインディングとTask Tree 親タスク 子タスク 子タスク
同期関数から非同期関数を呼ぶ方法 Task イニシャライザー • 非同期コンテキストを提供 • 同期関数内から非同期関数を呼べる • コールバックはすぐに呼ばれる •
返り値の Task インスタンスからマニュアルで キャンセルできる • 親タスクの優先度や actor, タスクローカル値 を引き継ぐ Task.detached • 非同期コンテキストを提供 • 同期関数内から非同期関数を呼べる • コールバックはすぐに呼ばれる • 返り値の Task インスタンスからマニュアルで キャンセルできる • 親タスクの優先度や actor, タスクローカル値 を引き継がない
TaskイニシャライザーとTask.detached • Task.detached は MainActor を引き継 がない -> ログ送信な どメインスレッドで不
要な処理に向く • Task は MainActor を 引き継ぐ -> メインス レッドで実行
マニュアルキャンセル • Task のイニシャライザーを保持しておけば、キャ ンセルが必要なときに cancel メソッドでキャンセル できる
キャンセルのハンドリング • checkCancellation: Task が キャンセルされている場合に CancellationError を返す ◦ キャンセルを呼び出し元
に伝える • isCancelled: キャンセルかど うか Bool 値で判断 ◦ キャンセル時追加処理が 可能 独自の追加処理
iOS 13, 14で非同期関数を使う
XcodeのリリースとSwift Concurrency対応状況 • Xcode 13 ◦ 2021 年 9 月
21 日リリース ◦ Swift Concurrency 機能は iOS 15 のみ • Xcode 13.2 ◦ 2021 年 12 月 13 日リリース ◦ Swift Concurrency 機能が iOS 13, 14 にもバックポートされた ◦ ただし Swift パッケージがビルドできない不具合が見つかる • Xcode 13.2.1 ◦ 2021 年 12 月 17 日リリース ◦ Swift パッケージの不具合を修正
iOS 13, 14で非同期関数を使う • 言語機能としての Swift Concurrency 機能は使える • Foundation
での非同期関数は iOS 15 以上 ◦ URLSession の data メソッドなど • withCheckedThrowingContinuation と withCheckedContinuation で既存の コールバック関数を非同期関数にラップができる • アプリサポートバージョンが iOS 15 が下限になるまではラップした関数を呼び出 す
withCheckedContinuation • エラーをスローするしないコールバック関数を非同期関数にラップする • クロージャー内でラップする関数を呼ぶ • ラップする関数のコールバック内で continuation は確実に一回 resume
メソッドを 呼び出す ◦ 呼び出さないのはだめ ◦ 2回以上呼び出すのもだめ
withCheckedContinuation •
withCheckedThrowingContinuation • エラーをスローするコールバック関数を非同期関数にラップする • クロージャー内でラップする関数を呼ぶ • ラップする関数のコールバック内で continuation は確実に一回 resume
メソッドを 呼び出す • resume(returning:) メソッド ◦ ラップした関数の戻り値を引数にする • resume(with: ) ◦ Result 型で返す • continuation.resume(throwing:) ◦ エラー型で返す
withCheckedThrowingContinuation •
まとめ
まとめ • async/await で非同期処理を同期関数のように記述できるようになった • それによって読みやすさが向上し、コールバックの呼び忘れなどのミスを防 げるようになった • マルチスレッドでよくある不具合、データ競合を防ぐ新しい型、 actor
が登場 した ◦ ただし、競合状態はまだ防げない • 非同期処理は Task という単位で行われる • iOS 13, 14 でも Swift Concurrency は使える
参考資料 • Race condition vs. Data Race: the differences explained
• データ競合 (data race) と競合状態 (race condition) を混同しない • Protect mutable state with Swift actors • https://github.com/apple/swift-evolution/blob/main/proposals/0316-glo bal-actors.md • Explore structured concurrency in Swift • Meet async/await in Swift