title: How SwiftUI detects there are @State variable values passed to subviews?
body: <p>Below is a simple example which doesn't use <code>@Binding</code>, but pass <code>@State</code> variable value directly to subviews (through closure).</p>
  <pre><code> 1  import SwiftUI
     
   2  struct ContentView: View {
   3      @State var counter = 0
   4      var body: some View {
   5          print(&quot;ContentView&quot;)
   6          return VStack {
   7              Button(&quot;Tap me!&quot;) { self.counter += 1 }
   8              LabelView(number: counter)
   9          }
  10      }
  11  }
     
  12  struct LabelView: View {
  13      let number: Int
  14      var body: some View {
  15          print(&quot;LabelView&quot;)
  16          return Group {
  17                  Text(&quot;You've tapped \(number) times&quot;)
  18          }
  19      }
  20  }
  </code></pre>
  <p>Tapping the button modifies <code>@State</code> variable, which then causes both<code>ContentView</code> and <code>LabelView</code> get updated. A common explanation is that, because the toplevel view's <code>@State</code> variable changes, so the toplevel ivew's body is re-executed.</p>
  <p>But my experiments show that it's not that simple.</p>
  <ul>
  <li><p>For example, if I remove the <code>LabelView(number: counter)</code> call (see line 8 above) in the code, then tapping the button won't get ContentView.body() executed.</p>
  </li>
  <li><p>For another example, if I pass <code>@Binding</code> variable, instead of <code>@State</code> variable value to subview, then tapping the button won't get ContentView.body() executed either.</p>
  </li>
  </ul>
  <p><strong>So it seems that SwiftUI knows that if toplevel view's <code>@State</code> variable value is passed to subviews. I wonder how it determines that?</strong> I know compiler has this kind of information. But SwiftUI is a framework written in Swift. I don't think Swift has this kind of feature.</p>
  <p>While writing this question, I realize one possible way to do it. Note the above code is executed when creating initial view hierarchy. That is, if a <code>@State</code> variable is passed to a subview, its getter must get executed <em>before</em> view update. It seems SwiftUI might take advantage of this to determine if there are <code>@State</code> variables is passed to a subview (or accessed in toplevel view's body).</p>
  <p>Is that the way how it works? I wonder how you guys understand it? Thanks.</p>
  <hr />
  <p><strong>Update 1</strong>:</p>
  <p>Below is my summary of the discussion with @Shadowrun, who helped to put the pieces together. I don't know if it's really what happens under the hood, but it seems reasonable to me. I write it down in case it helps others too.</p>
  <ol>
  <li><p>SwiftUI runtime maintains view hiearchy somehow. For example,</p>
  <ul>
  <li><p>For subviews, this may be done with the help of viewbuilders. For example, viewbuilders registers subviews with the runtime.</p>
  </li>
  <li><p>For toplevel view, this may be done by runtime (note toplevel view's body is a regular computed property and not transformed by viewbuilder).</p>
  </li>
  </ul>
  </li>
  <li><p>SwiftUI can detect if state variable is read or written through its getter/setter.</p>
  </li>
  <li><p>This is hypothesis. When SwiftUI creates the initial view hiearchy, it does the following for each view:</p>
  <ul>
  <li><p>Set current view</p>
  </li>
  <li><p>Run the view's body code (I find that body of layout types like VStack has <code>Never</code> type. I suppose it has an equivalent way to iterate through its subviews).</p>
  </li>
  <li><p>If SwiftUI detects that the view's state variable is read, it save the dependency between that state variable and the view somewhere. So if the app modifies that state variable later, the view's body will be executed to update the view.</p>
  <ul>
  <li><p>Scenario 1: If the view body doesn't read the view's state variable, it won't trigger the above mechanism. As a result, the view won't be updated when the app modifies the state variable.</p>
  </li>
  <li><p>Scenario 2: If the view pass its state variable to its subview through binding (that is, the state variable's projectedvalue), it won't trigger the above mechanism either, because reading/writing a state variable's projectedvalue is through Binding property wrapper's getter/setter, not State property wrapper's getter/setter.</p>
  </li>
  </ul>
  </li>
  </ul>
  </li>
  </ol>
  <hr />
  <p><strong>Update 2</strong>：</p>
  <p>An interesting detail. Note the <code>+=</code> operator in line 7. It's usually implemented as reading and writing. So the button handler in line 7 read state variable also. However, button handler isn't called when creating initial view hierarchy, so based on the theory above SwiftUI won't recall <code>ContentView.body</code> just because of line 7. This can be proved by removing line 8.</p>
  <p><strong>Update 3</strong>：</p>
  <p>I have a new and much simpler explanation to the original question. In my original question I asekd:</p>
  <blockquote>
  <p>So it seems that SwiftUI knows that if toplevel view's @State variable value is passed to subviews. I wonder how it determines that?</p>
  </blockquote>
  <p>It's a wrong question. It's very likely that SwiftUI doesn't really knows that the state is passed to subview. Instead it just knows that the state is accessed in the view's body(perhaps using a similar mechanism I described above). So, if a view's state changes, it reevaluates the view's body. Just this simple rule.</p>