「SwiftUIでMVVMやるシンプルなパターン3つの違い」が分からなかったので、初学者が調べながら説明してみる。
初学者のため、一部理解しきれていない部分があったので、調べてみる。
上記記事のまとめ
1つ目のやり方

2つ目のやり方

3つ目のやり方
初学者は違いが分からなかった。
ポイント
ポイントとしては、
- 子孫Viewの使い回しができるかどうか(ViewがViewModelに依存しているかどうか)
- バケツリレーをしなければならないか、どうか(EnvironmentObjectを用いるかどうか)
挙げられる。
なぜそういったことが生じてしまうのか。一つひとつ深ぼっていく。
子孫Viewの使い回しができるかどうか(ViewがViewModelに依存しているかどうか)
1,2 のSubViewのサンプルコードを見てみよう。
1のサンプルコード
struct SampleSubView: View {
@ObservedObject var viewModel: SampleViewModel
init(viewModel: SampleViewModel) {
self.viewModel = viewModel
}
var body: some View {
VStack(spacing: 8) {
Text(viewModel.stars)
Button("Change Stars Length") {
viewModel.changeStarsLength(Int.random(in: 1 ..< 10))
}
}
}
}
2のサンプルコード
struct SampleSubView: View {
@Binding private var stars: String
private var handler: (Int) -> Void
init(stars: Binding<String>, action handler: @escaping (Int) -> Void) {
self._stars = stars
self.handler = handler // クロージャーを保持
}
var body: some View {
VStack(spacing: 8) {
Text(stars)
Button("Change Stars Length") {
handler(Int.random(in: 1 ..< 10))
}
}
}
}
初期値として設定すべき、プロパティの型を見て頂きたい。
init(...) {...}
の中身を見るだけでも良いです。
1の場合は、SampleViewModel
を設定
2の場合は、Binding<String>
(Int) -> Void
を設定
このようなViewの設定が必要になってくる。
1では、SampleViewModel
という型を用いた実装でしか、このViewを用いることができません。
だが、
2では、String型
と引数がInt型である関数
を初期値に代入することができれば、どこの画面でも用いることができます。
例えば、SampleSubView
で、お気に入りボタン♡ を実装していたとしよう。
そのお気に入りボタンの実装を、画面1でも使いたいし、画面3、画面4でも使いたくなった場合には、例2の方法の方が望ましい。例1はSampleViewModel
に依存しているので、他の画面でもSampleViewModel
を用いる必要があり、望ましくない実装になってします。
これらの状態が依存している状態であると、筆者は解釈しました。
バケツリレーをしなければならないか、どうか(EnvironmentObjectを用いるかどうか)
@ObserverdObjectとの違いは、バケツリレーのように子Viewに引き渡す必要がありません。インスタンスを階層トップのViewに紐付けると、アプリケーション全体からアクセス可能になります。
アプリケーション全体で共有するようなデータを扱う用途で使用します。
→階層のトップのView
に紐付けると、どこでもEnvironmentObject
を用いて呼び出すことができるよということでした。ObserverObject
であれば、わざわざ子Viewに値を渡す必要があるため、それが孫Viewや、ひ孫View、玄孫View、来孫View...と渡していかなければなりません。その問題に対して、EnvironmentObject
は、バケツリレーせずに、来孫Viewに値を渡すことができます。便利ですよね。
祖父母Viewには渡せないので、ご注意を。
参考
他にも良い方法があれば、コメントいただけると大変うれしいです。
良かったと思ったら、いいねやTwitterのフォローよろしくお願いいたします!
個人でアプリを作成しているので、良かったら覗いてみてください!
Discussion