Search code examples
swiftuicombine

Does SwiftUI removeDuplicates from a subscriber to an @Published property?


If I have an ObservableObject like...

class Foo: ObservableObject {
  @Published var value: Int = 1

  func update() {
    value = 1
  }
}

And then a view like...

struct BarView: View {
  @ObservedObject var foo: Foo

  var body: some View {
    Text("\(foo.value)")
      .onAppear { foo.update() }
  }
}

Does this cause the view to constantly refresh? Or does SwiftUI do something akin to removeDuplicates in the subscribers that it creates?

I imagine the latter but I've been struggling to find any documentation on this.


Solution

  • onAppear is called when the view is first brought on screen. It's not called again when the view is refreshed because a published property has updated, so your code here would just bump the value once, and update the view.

    If you added something inside the body of view that updated the object, that would probably trigger some sort of exception, which I now want to try.

    OK, this:

    class Huh: ObservableObject {
        @Published var value = 1
        func update() {
            value += 1
        }
    }
    
    struct TestView: View {
        @StateObject var huh = Huh()
        
        var body: some View {
            huh.update()
            return VStack {
                Text("\(huh.value)")
            }.onAppear(perform: {
                huh.update()
            })
        }
    }
    

    Just puts SwiftUI into an infinite loop. If I hadn't just bought a new Mac, it would have crashed by now :D