カルボナーラ街道

計測と観察

Swift Concurrency メインスレッドクイズ(2) 2問

実行環境

>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

gist.github.com

答えと解説

答え

false

解説

前提として、Detached Taskは実行元のactor contextを引き継がないので、ViewControllerに暗黙的に付与されているGlobal ActorであるMain Actorのexecutor上で y.f() は実行されない。

0316-global-actors.md に載っている例だが、説明が初見で分からなったので整理した。

プロポーザルに出てくるwitnessというのは特定のプロトコル準拠内でその要件を満たすために使用される定義のこと。プロポーザルを読むと、プロトコルのメソッド実装がそのプロトコルに適合する宣言と同じ型定義やextension内にある場合のみ、actor isolationの推論が有効になるようで、今回は YP の準拠と YP の要件実装が別のためactor isolationの推論が有効にならず、P のメソッド定義に付与されている @MainActorY で有効にならない。YP の準拠と Y の要件実装を同じ箇所で行うと推論が効くとのことなので試すと、trueになった。

gist.github.com

これまでの説明を踏まえてコードを振り返ると、y.f() の前にawaitキーワードを書くことを要求されなかったので、Main Actorにisolatedされていないことが分かる。

Question 2

gist.github.com

答えと解説

答え

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となる。