😊

@StateObjectとは

2023/05/01に公開

@StateObjectは、SwiftUIで使われるプロパティラッパーの1つで、View内で使用する状態を管理するために使用されます。SwiftUIにおいて、@State@BindingはView内で使用される状態を管理するために広く使われていますが、これらのプロパティラッパーでは、状態の変更がViewの再描画をトリガーするように設計されています。

一方、@StateObjectは、Viewとは独立して生存するオブジェクトを管理するために使われます。通常、このプロパティラッパーは、ViewModelやその他のオブジェクトを管理するために使用されます。Viewの状態が変更されても、@StateObjectで管理されるオブジェクトの状態が変更されると、Viewが再描画されます。

@StateObjectは、iOS 14以降で利用可能で、SwiftUIにおけるMVVMアーキテクチャでViewとViewModelの接続を簡素化するためによく使用されます。

以下は、@StateObjectを使ってTimerPageのViewModelを管理する例です。

struct TimerPage: View {
  @StateObject var viewModel: TimerViewModel
  
  init(time: Int) {
    self._viewModel = StateObject(wrappedValue: TimerViewModel(time: time * 60))
  }
  
  var body: some View {
    VStack {
      Text(viewModel.remainingTime.asTimeString)
        .onAppear {
          viewModel.start()
        }
    }
    .onDisappear {
      viewModel.stop()
    }
  }
}

TimerPageviewModelプロパティには、@StateObjectが使用されています。また、TimerViewModelのインスタンスは、StateObjectの初期化子に渡され、wrappedValueとしてラップされています。

onAppearonDisappearでは、それぞれViewModelのstart()stop()メソッドが呼び出されます。

これにより、TimerPageの表示中にViewModelが維持され、Viewが再描画された場合でもViewModelの状態が維持されるようになります。

簡単に言えば、@StateObjectは、Viewとは独立して存在するオブジェクトを作成し、Viewが再描画された場合でもオブジェクトの状態を保持するために使用されるプロパティラッパーです。

Discussion