Closed8

Swift5 & Strict Concurrency Checking(complete)で警告では無くコンパイルエラーが出る件について調べるスレ

ピン留めされたアイテム
tanakotanako

https://zenn.dev/link/comments/441f784c272216 のエラーが出たので調べた。

結論

Swift 5.5 までは UIKit で付与される MainActor は MainActor(unsafe) なので非隔離ドメインから同期的なアクセスをしてもコンパイルエラーにはならないものの、Swift5.6以上のある時点から UIKit側の MainActor(unsafe) が MainActor に変わりコンパイルエラーとなった模様。

UIKit の class に付与された MainActor の実態

  • swift5.8.1以上〜swift6以下: MainActor
  • swift5.6..5.8: 未検証なので不明
  • swift5.5: MainActor(unsafe)

同期非隔離ドメインからUIKit由来のMainActor隔離メソッドの呼び出しがどうなるか

Xcode 14.3.1以上〜15.4以下 & strict concurrency checking=complete
UIKitのextensionを同期非隔離ドメインから呼ぶとコンパイルエラーになる。

Xcode 14以上〜14.3以下 & strict concurrency checking=complete
未検証だが、UIKitのextensionを同期非隔離ドメインから呼ぶとコンパイルエラーになりそう。

Xcode 13(swift5.5)
未検証。Xcode13でUIKitのextensionをnon-isolatedなコンテキストで呼んでも MainActor(unsafe) なので検査は無視されコンパイルエラーにならない。(明示的にUIViewControllerをサブクラスして@MainActorを付与したケースは異なりそう)

tanakotanako

手元のプロジェクト(Xcode15.4)の Strict Concurrency Checking を Complete にしてみるも、UIViewController の extension のメソッドを呼び出すコードで Call to main actor-isolated instance method 'xxx()' in a synchronous nonisolated context 的なコンパイルエラーが出て戸惑う。Strict Concurrency Checkingってswift5では警告にしかならないんじゃなかったっけ..?

tanakotanako

Strict Concurrency Checkingってswift5では警告にしかならない

↑の想定が正しいかを調べる。Enabling Complete Concurrency Checking というドキュメントがあったので読む。
https://www.swift.org/documentation/concurrency/

you can enable the compiler’s actor isolation and Sendable checking as warnings in the Swift 5 language mode

とか

To enable complete concurrency checking when running swift or swiftc directly at the command line, pass -strict-concurrency=complete:

などからは警告に留まるような書き方に見える。

tanakotanako

MainActor(unsafe) が有効になる

はどのタイミングで有効になったんだろう。

tanakotanako

swift 5.10から変わっていったのかな(改めて 5.10 のリリースは読み込んどきたい)
https://www.swift.org/blog/swift-5.10-released/

5.9.1と5.9をそれぞれtoolchain変えて試してみる。

ここで古いswift toolchainを落としてみる
https://www.swift.org/download/

toolchainをインストールした後は Xcode > Toolchains から切り替えできる。
https://www.swift.org/install/macos/package_installer/

結果、5.9.1と5.9でも https://zenn.dev/link/comments/441f784c272216 のエラーは出たまま。

tanakotanako

https://forums.swift.org/t/concurrency-in-swift-5-and-6/49337 UIKitのNS_SWIFT_UI_ACTORはSwift5.5ではMainActor(unsafe) なので利用側が concurrency の機能を使っている時だけ強制されると思います

https://x.com/rintaro/status/1442543055597301765

前に教えてもらったんですが、Swift 5.5の時点ではUIViewControllerなどがMainActorなのはオプトインっぽい

https://x.com/giginet/status/1470975364268761096

なるほど。swift5.6以上のどこかのタイミングではUIKitのNS_SWIFT_UI_ACTORMainActor(unsafe)ではなくMainActorになる。なのでUIViewControllerのextensionの呼び出し側でエラーになるという流れだった。(コミュニティの皆さんの会話助かる)

tanakotanako

以下のような話もありややこしい

データ競合により意図しない値の変更に悩まされた時に、原因調査の手段として以前からコンパイラ・オプション-strict-concurrency=completeは有った。このオプションはコードを部分的に調査するものだったのが、5.10からすべての安全でないコードにコンパイルエラーを発する様になった。

https://zenn.dev/tana00/articles/c820928c53629c

このスクラップは1ヶ月前にクローズされました