🐥

SingletonのSwift 6警告対応

2024/08/19に公開

はじめに

既存コードのSwift 6対応をする場合、例としてpublic static let shared = .init()ないわゆるSingleton作成箇所で次のような警告が出る状況になるはずです。

Static property 'shared' is not concurrency-safe because it is not either conforming to 'Sendable' or isolated to a global actor; this is an error in Swift 6

shared自体が'Sendable'プロトコルに準拠させるかアクター分離するかって感じで警告されています。

実際はshared自体に何かすることよりも型自体を変更することが多いでしょう。手段はさまざまなのでこういうときどういうシチュエーションでどうやるか、今の考えをフローチャートにしておきます。他にもやり方あったら教えてください。

フローチャート

自由に改変しやすいようにmermaidのコードも載せておきます。

graph TD
    Warning[SingletonでSwift 6のアクター分離に関する警告される時]
    Warning --> IsAHelper{それ自身はHelper?\nつまり状態(変数)がなく\n非同期処理でもない}
    IsAHelper -- YES--> IsSendable{それstructにできる?\nもしくは既に\nstructじゃない?}
    IsSendable -- YES --> Sendable[型に対してSentable準拠させる]
    IsSendable -- NO --> UncheckedSendable[型に対して@unchecked Sentable準拠]
    IsAHelper -- NO--> LegacyThreadsafe{スレッドセーフ?\nつまりレガシーな方法\nか何かで対策されてる}
    LegacyThreadsafe -- YES --> UncheckedSendable
    LegacyThreadsafe -- NO --> Actor{そのSingletonをMainActorにしたい}
    Actor -- YES --> MainActor[MainActor]
    Actor -- NO --> UseSingletonActorIso{同期処理から\n呼び出されてる?}
    UseSingletonActorIso -- YES --> Mendoi[呼び出し側の設計を変える必要があるので\n頑張れ]
    UseSingletonActorIso -- NO --> Raku[awaitつけるだけで苦労しない気がする]

経緯

https://x.com/omochimetaru/status/1825402485084979428

Discussion