質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.40%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Q&A

解決済

1回答

189閲覧

@stateの外部からのアクセスについて

kentaronagata

総合スコア25

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

0グッド

0クリップ

投稿2024/05/20 07:27

実現したいこと

@stateについて実際に使ってみて、外部からアクセスできないことを確認してみたい。

発生している問題・分からないこと

SwiftUI初心者です。
エラーが出ているわけではありませんが、プロパティラッパーである@Stateについての挙動がよくわかっていません。
サイトなどで@Stateを定義すると、「そのプロパティへのアクセスは宣言されたView内でのみとなる。」とあったので実際にアクセスできないか確認してみるコードを記述してみました。
外部からアクセスする「Outside」といった構造体を書いて、実行してみたのですが、以下の写真のようにアクセスできたように見られます。
イメージ説明

該当のソースコード

Swift

1import SwiftUI 2 3struct ContentView: View { 4 5 @State var isStateEnabled : Bool = false 6 7 8 var body: some View { 9 VStack { 10 HStack{ 11 Text(isStateEnabled ? "有効" : "無効") 12 .padding() 13 Toggle("", isOn: $isStateEnabled) 14 .padding() 15 // onchangeモディファイアのofの引数には監視対象となるプロパティを記入する 16 .onChange(of: isStateEnabled){ 17 print("isStateEnabledの状態:\(isStateEnabled)") 18 Outside().testAccess() 19 } 20 } 21 } 22 } 23} 24 25struct Outside { 26 func testAccess() { 27 let view = ContentView() 28 print(view.isStateEnabled) 29 } 30// } 31 32} 33 34#Preview { 35 ContentView() 36} 37 38 39
特になし

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

@stateの後に「private」をつけるとアクセスできないといったエラーが生じました。

error

1'isStateEnabled' is inaccessible due to 'private' protection level

@stateのみの記述だとプロパティーを監視するだけでどこからでもアクセスできてしまうのでしょうか?
それとも上記に挙げた写真から、トグルボタンを押すとView内の変数の更新が確認できたのですが、外部から接続確認するために記述した、Outsideの構造体の中の関数の変数は「false」のままで更新されていないことがわかります。
更新されていない = アクセスできていないと考えるべきでしょうか?
この@stateについてわかりやすく教えていただけたら幸いです。
よろしくおねがいします。

補足

Xcode 15.4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

@stateのみの記述だとプロパティーを監視するだけでどこからでもアクセスできてしまうのでしょうか?

アクセスできるみたいですね。

Outsideの構造体の中の関数の変数は「false」のままで更新されていないことがわかります。
更新されていない = アクセスできていないと考えるべきでしょうか?

確認するコードがあまり適切ではないかもしれないですね。
SwiftUIのビューをbody以外で生成するとか、
他のメソッドの引数に渡すとか、
本来はそういう使い方はしないのかなと思いますが・・
無理やり試すなら下のようなコードになると思います。
*質問欄のコードはtestAccessで毎回別のContentViewのインスタンスを生成しているからfalseのままになっているだけですね

swift

1import SwiftUI 2 3struct ContentView: View { 4 @State var isStateEnabled : Bool = false 5 var body: some View { 6 VStack { 7 HStack{ 8 Text(isStateEnabled ? "有効" : "無効") 9 .padding() 10 Toggle("", isOn: $isStateEnabled) 11 .padding() 12 // onchangeモディファイアのofの引数には監視対象となるプロパティを記入する 13 .onChange(of: isStateEnabled){ 14 print("isStateEnabledの状態:\(isStateEnabled)") 15 Outside().testAccess(self) // *****修正 16 } 17 } 18 } 19 } 20} 21 22struct Outside { 23 func testAccess(_ view: ContentView) { // *****修正 24// let view = ContentView() // *****修正 25 print(view.isStateEnabled) 26 } 27} 28 29#Preview { 30 ContentView() 31}

下のようなログになります。

log

1isStateEnabledの状態:true 2true 3 4isStateEnabledの状態:false 5false 6 7isStateEnabledの状態:true 8true 9 10isStateEnabledの状態:false 11false

公式のドキュメントの引用です。

Declare state as private in the highest view in the view hierarchy that needs access to the value.
値にアクセスする必要があるビュー階層で最も高いビューで、状態をプライベートとして宣言します。

State | Apple Developer Documentation

一般的なSwiftUIの思想としては、
一番親になるビューで@Stateを定義して、子孫のビューに渡していく感じになると思います。
そういう思想においては、親のビューのさらに外側から使用しないのが普通になりますので、
@Stateは基本的に プライベートな宣言になると思います。 上の公式のドキュメントの引用に記載されているようにプライベートと宣言・実装するべきと思います。

こういう前提ですので、公式以外のサイトでは下のような記載もあるのかなと思います。

サイトなどで@Stateを定義すると、「そのプロパティへのアクセスは宣言されたView内でのみとなる。」とあったので

最も信頼できる情報は公式のもの以外にはないので、慣れないと大変かもしれませんが、まずは公式のドキュメントを読むことを優先した方が良いかなと個人的には思います。

投稿2024/05/20 13:37

編集2024/05/20 13:41
yametai

総合スコア255

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kentaronagata

2024/05/21 02:13

更新されていない理由は、24行目のインスタンス生成時に毎回初期化されるため、ずっと「false」だったということですね!ありがとうございます。 公式を見るとあまり@state単体では使用しなさそうですね。privateで使用して、子ビューとデータを連携する際は、@Bindingを使用していました。 基本@state宣言する時は、privateも記述するようにします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.40%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問