title: How to prod a SwiftUI view to update when a model class sub-property changes?
body: <p>I've created a trivial project to try to understand this better. Code below.</p>
  
  <p>I have a source of data (<code>DataSource</code>) which contains a <code>@Published</code> array of <code>MyObject</code> items. <code>MyObject</code> contains a single string. Pushing a button on the UI causes one of the <code>MyObject</code> instances to update immediately, plus sets off a timer to update a second one a few seconds later.</p>
  
  <p>If <code>MyObject</code> is a struct, everything works as I imagine it should. But if <code>MyObject</code> is a class, then the refresh doesn't fire.</p>
  
  <p>My expectation is that changing a struct's value causes an altered instance to be placed in the array, setting off the chain of updates. However, if <code>MyObject</code> is a class then changing the string within a reference type leaves the same instance in the array. Array doesn't realise there has been a change so doesn't mention this to my <code>DataSource</code>. No UI update happens.</p>
  
  <p>So the question is – what needs to be done to cause the UI to update when the <code>MyObject</code> class's property changes? I've attempted to make <code>MyObject</code> an <code>ObservableObject</code> and throw in some <code>didchange.send()</code> instructions but all without success (I believe these are redundant now in any case).</p>
  
  <p>Could anyone tell me if this is possible, and how the code below should be altered to enable this? And if anyone is tempted to ask why I don't just use a struct, the reason is because in my actual project I have already tried doing this. However I am using collections of data types which modify themselves in closures (parallel processing of each item in the collection) and other hoops to jump through. I tried re-writing them as structs but ran in to so many challenges.</p>
  
  <pre><code>import Foundation
  import SwiftUI
  
  struct ContentView: View
  {
      @ObservedObject var source = DataSource()
  
      var body: some View
      {
          VStack
          {
              ForEach(0..&lt;5)
              {i in
                  HelloView(displayedString: self.source.results[i].label)
              }
              Button(action: {self.source.change()})
              {
                  Text("Change me")
              }
          }
      }
  }
  
  struct HelloView: View
  {
      var displayedString: String
  
      var body: some View
      {
          Text("\(displayedString)")
      }
  }
  
  class MyObject // Works if declared as a Struct
  {
      init(label: String)
      {
          self.label = label
      }
  
      var label: String
  }
  
  class DataSource: ObservableObject
  {
      @Published var results = [MyObject](repeating: MyObject(label: "test"), count: 5)
  
      func change()
      {
          print("I've changed")
          results[3].label = "sooner"
          _ = Timer.scheduledTimer(withTimeInterval: 2, repeats: false, block: {_ in self.results[1].label = "Or later"})
      }
  }
  
  struct ContentView_Previews: PreviewProvider
  {
      static var previews: some View
      {
          ContentView()
      }
  }
  </code></pre>