@StateObjectとは
@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()
}
}
}
TimerPage
のviewModel
プロパティには、@StateObject
が使用されています。また、TimerViewModel
のインスタンスは、StateObject
の初期化子に渡され、wrappedValue
としてラップされています。
onAppear
とonDisappear
では、それぞれViewModelのstart()
とstop()
メソッドが呼び出されます。
これにより、TimerPage
の表示中にViewModelが維持され、Viewが再描画された場合でもViewModelの状態が維持されるようになります。
簡単に言えば、@StateObjectは、Viewとは独立して存在するオブジェクトを作成し、Viewが再描画された場合でもオブジェクトの状態を保持するために使用されるプロパティラッパーです。
Discussion