【Swift】Actorがうまく動作しない(シミュレータ)

Swift

Actorの動作確認は実機で行うべきです。
シミュレータでは実機と異なる動作をする場合があります。

おそらくシミュレータに割り当てられているスレッド数が少ないようで、
異なるActorでも同一スレッドで動作します。

結果として、本来は異なるActorで並行して走る処理が、
同一Actorで実行したように順次処理される場合があります。

もちろんこれは実機でも起こり得る話ではあり、
許容されるスレッド数を超える大量のマルチスレッド処理を行なった場合は、
実機でも起こ可能性はあります。

サンプル

@globalActor
actor MyActor:GlobalActor {
    static let shared = MyActor()
}

@globalActor
actor MyActor2:GlobalActor {
    static let shared = MyActor2()
}

class TestModel2:ObservableObject{
    @MainActor @Published var count = 0
    
    @MyActor
    func countUp() async {
        sleep(5)
        await MainActor.run{
            count += 1
        }
    }
    
    @MyActor2
    func countUp2() async {
        sleep(5)
        await MainActor.run{
            count += 1
        }
    }
}
struct ActorMarkedView: View {
    
    @StateObject var testModel2 = TestModel2()
    
    var body: some View {
        VStack {
            Text(String(self.testModel2.count))
                .padding()
            Button("CountUp"){
                Task {
                    await testModel2.countUp()
                }
            }
            Button("CountUp"){
                Task {
                    await testModel2.countUp2()
                }
            }
        }
    }
}

actorの記事で使ったやつです。

本来はcountUpとcountUp2でActorが違う為、並列で実行されます。
しかし私の環境のシミュレータではcountUpとcountUp2が順に実行されました。

おそらくシミュレータに割り当てられているスレッドが少なく、
メインスレッドとMyActorを実行しているスレッドで上限に達しており、
空きスレッドがない為MyActorを待った後に
空いたスレッドでMyActor2を実行しているのではないかと思います。

コメント

  1. […] […]

タイトルとURLをコピーしました