実行環境
>swift --version swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4) Target: arm64-apple-macosx14.0 >xcodebuild -version Xcode 15.3 Build version 15E204a
モチベーション
まだまだSwift Concurrencyパワーが足りていない。読み、書き、動かし、クイズを作り、Swift Concurrencyを身体に馴染ませる。
過去のクイズは以下。
Question 1
答えと解説
答え
false
解説
前提として、Detached Taskは実行元のactor contextを引き継がないので、ViewControllerに暗黙的に付与されているGlobal ActorであるMain Actorのexecutor上で y.f()
は実行されない。
0316-global-actors.md に載っている例だが、説明が初見で分からなったので整理した。
プロポーザルに出てくるwitnessというのは特定のプロトコル準拠内でその要件を満たすために使用される定義のこと。プロポーザルを読むと、プロトコルのメソッド実装がそのプロトコルに適合する宣言と同じ型定義やextension内にある場合のみ、actor isolationの推論が有効になるようで、今回は Y
の P
の準拠と Y
の P
の要件実装が別のためactor isolationの推論が有効にならず、P
のメソッド定義に付与されている @MainActor
が Y
で有効にならない。Y
の P
の準拠と Y
の要件実装を同じ箇所で行うと推論が効くとのことなので試すと、trueになった。
これまでの説明を踏まえてコードを振り返ると、y.f()
の前にawaitキーワードを書くことを要求されなかったので、Main Actorにisolatedされていないことが分かる。
- https://github.com/apple/swift-evolution/blob/main/proposals/0316-global-actors.md
- https://github.com/apple/swift/blob/a2eb9e04cc8ae4d7e951924738ad6606cdfbfbb0/include/swift/AST/Witness.h#L32-L35
Question 2
答えと解説
答え
true
解説
0316-global-actors.md にて、Global Actorが付与された wrappedValue
を持つプロパティを含む構造体やクラスはそのProperty Wrapperからactor isolationの推論が行われるようになった。
@TwelveOrLess
Property Wrapperの wrappedValue
はMain Actorにisolatedされているため、それを持つ構造体 SmallRectangle
はMain Actorにisolatedされる。SmallRectangle
のメソッドもMain Actorにisolatedされるためメインスレッドで実行される。呼び出し時に await
が必要になるのでヒントがあった。
なお、
0401-remove-property-wrapper-isolation にて、Swift 6 language modeではこの推論は行われなくなるためfalseになる。コンパイル時に -enable-upcoming-feature DisableOutwardActorInference
を渡すとfalseになることを確認した。今回の実行環境であるSwift 5.10ではデフォルトでその機能は有効になっていないためtrueとなる。
- https://github.com/apple/swift-evolution/blob/main/proposals/0316-global-actors.md
- https://github.com/apple/swift-evolution/blob/main/proposals/0401-remove-property-wrapper-isolation.md
- https://developer.apple.com/documentation/swiftui/stateobject/wrappedvalue
- プロポーザル中で
@StateObject
の例が載っていた。wrappedValue
に@MainActor
が付与されている。
- プロポーザル中で