見出し画像

New SwiftUI - Property Wrappers-その他のもの。

@StateObject

@ObservedObjectの不具合を改良したもの、

を参考に一部抜き出しますが、

ローカルの状態を保持したい時に
これまで@ObservedObjectを利用しようとしていたところで
@StateObjectを利用するのが良いのではないかと思います。
他からイニシャライザを経由して利用するような場合はこれまで通り@ObservedObjectを利用することでよりコードを読んでいる人へ意図を伝えやすくなる

ということらしいです。詳しくは以下

で”instantiates an observable object.”と説明してあります。

以下サイトで例示しながら詳しく説明されています。

This is a problem! The reason is that every time you change or update the local count in the ContentView, it renders the view again. The rendering instantiate the CounterView, creating a new instance of Counter class.

To fix this issue Apple introduced a new property wrapper called @StateObject. State object wrapper will persist the value during the renders. Update your CounterView code to use @StateObject as shown below:

この部分に"@ObservedObject"を使った時に起きる不具合と、対処について書いてあります。

要するに、ContentViewのローカルなアップデート、この場合だとボタンを押して数字を"1"づつ増やすごとにリセットされてしまうということが発生してしまう。新しいインスタンスをCounter classが作るごとにレンダリング(初期化)されてしまいます。

そこで改善されたのが、"@StateObject"を使う方法だということです。


@SceneStorage

Sceneの値を保存することができるようにしてくれます。@AppStorageとは異なりUserDefaultsを利用はしないため、保存されている保証はされないとのことです。

参考サイト一部抜き出します。

Scene単位で値が共有できる仕組みで
フレームワーク側で
SceneStorageの値を管理し
初期化時に前回保持していた値があった場合は
自動で設定をしてくれるようです。
@AppStorageとは異なり
UserDefaultsを利用はせず
内部に値を保持しているようです。

の中のサンプルコード

struct ContentView: View {
   @SceneStorage("selectedTab") var selection = 0
   
   var body: some View {
       TabView(selection: $selection) {
           Text("Tab 1").tag(0)
           Text("Tab 2").tag(1)
       }
   }
}

のようなシーンの中での値の保存になるようです。シーンがなくなれば保存も無くなります。

この記事が気に入ったらサポートをしてみませんか?