SwiftUIの@ Stateとかの呪文について

botman_blue iOS

Xcode-12.5.1 Swift-5.4.2 iOS-14.0

はじめに

SwiftUI には some, @State, @Binding など色々な呪文が存在します。SwiftUI の呪文は下記のやつが関係しているそうです。例えば、同じ階層に View が 10 個までしか置けないのは Function Builder のしくみによるものです。

  • Implicit returns from single-expression functions
  • Function Builder
  • Opaque Result Type
  • Property Wrapper

参考
しくみから理解するSwiftUI

今回は Property Wrapper が関係する @State@Binding などについて記載します。

Property Wrapper

SwiftUI でよくみかける下記はすべて Property Wrapper です。

  • @State
  • @Binding
  • @Published
  • @StateObject
  • @ObservedObject
  • @EnvironmentObject

ざっくりいうと Property Wrapper はプロパティへのアクセス方法を指定できるしくみです。詳細は下記など参考にしてもらえれば。

Property Wrapper は下記のように wrappedValue とは別に projectedValue を定義できます。この projectedValue にアクセスする場合には変数の前に $ をつけます。@State のバインディングでみかける $ の正体はこいつです!後述する $ はすべて Property Wrapper の projectedValue だったのです。

State

View(struct)で値を更新するためのやつ。値の保持は SwiftUI フレームワークがおこなってくれており、値が更新されるたびに View(body とその子要素)も更新される模様。

ドキュメント:State

簡易実装。

参考:Data Flow Through SwiftUI(WWDC2019)

Binding

@State と違い親 View とか外部から値(参照)が渡されるときに使うやつ?

ドキュメント:Binding

簡易実装。

ObservableObjectとPublished

ObservableObject プロトコルに準拠したクラスの @Published プロパティの変更を通知するやつ。クラスの場合プロパティが変更されてもインスタンス自体は変更されないので @Published プロパティの変更を監視する。値が更新されると View も更新される。

ドキュメント:ObservableObject

ドキュメント:Published

クラスでしか使えないようです。

Important

The @Published attribute is class constrained. Use it with properties of classes, not with non-class types like structures.

どちらも Combine フレームワークのやつで Foundation に下記のように定義されているので Foundation をインポートするだけで使える模様。

簡易実装。

StateObject

@State のクラス版?
ライフサイクルは View の onAppear から onDisappear まで。View 自身で生成するときに使うやつ?下記の通り ObservableObject にのみ使える。

ドキュメント:StateObject

簡易実装。

ObservedObject

@Binding のクラス版?
ライフサイクルは Viewbody が更新されるまで。@StateObject と違い親 View とか外部から値(参照)が渡されるときに使うやつ?下記の通り ObservableObject にのみ使える。

ドキュメント:ObservedObject

簡易実装。

下記のように ObservedObjectStateObject を使うとライフサイクルの違いでボタン押下時に ObservedObject はリセットされます。

object

EnvironmentObject

ObservedObject と似たようなやつ?親 View.environmentObject を設定すると子孫 View からそのデータオブジェクトにアクセスできる。アプリ全体の設定値とかで使う?下記の通り ObservableObject にのみ使える。

ドキュメント:EnvironmentObject

簡易実装。

おわりに

なんとなく SwiftUI わかってきた気がする。たぶん SwiftUI のデータフローでは Single Source of Truth ていうのが重要な概念。

Data Essentials in SwiftUI(WWDC2020)08:55~で View を追加する際は下記の 3 つの質問を念頭に置けと言ってた。これも重要そう。

What data does this view need?

How will it use that data?

Where does the data come from?

参考

コメント

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