DEV Community

GoyesDev
GoyesDev

Posted on

[SUI] @StateObject vs @ObservedObject

Tanto @StateObject como @ObservedObject hacen que una vista de SwiftUI se actualice cuando detecte cambios en un objecto observado.

En ambos casos se requiere que el objeto a observar conforme el protocolo ObservableObject que sintetiza una propiedad objectWillChange que emite Void justo antes de que alguna propiedad marcada con @Published cambie y eso provoca que la vista de SwiftUI se vuelva a pintar.

class ContentViewModel: ObservableObject {
  @Published var count = 0

  func incrementCounter() {
    count += 1
  }
}
Enter fullscreen mode Exit fullscreen mode

Lo anterior puede llevar a pensar que es obligatorio tener @Published, sin embargo, en realidad no lo es: se puede emitir un evento en objectWillChange manualmente como se muestra a continuación:

class ContentViewModel: ObservableObject {
  private(set) var count = 0

  func incrementCounter() {
    count += 1
    objectWillChange.send()
  }
}
Enter fullscreen mode Exit fullscreen mode

Puede ser conveniente invocar objectWillChange manualmente cuando se debe modificar varias propiedades a la vez: Si fueran @Published podrían provocar que la vista se repinte varias veces, así que conviene que sean propiedades simples (sin @Published) y manipular manualmente el objectWillChange.

Observar cambios de un ObservableObject

Tanto @ObservedObject como @StateObject envuelven una instancia de un objeto que conforma ObservableObject. Cada vez que objectWillChange emita un valor, la vista se vuelve a pintar extrayendo los valores de ContentViewModel.

struct ContentView: View {
//  @StateObject var viewModel = ContentViewModel()
  @ObservedObject var viewModel = ContentViewModel()

  var body: some View {
    VStack {
      Text("Contador: \(viewModel.count)")
      Button("Incrementar") {
        viewModel.incrementCounter()
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Diferencia entre @StateObject y @ObservedObject

Los objetos marcados con @StateObject no se reconstruyen cada vez que la vista vuelve a pintarse. Por esta razón, NO SE DEBE USAR @ObservedObject PARA CREAR UNA DEPENDENCIA, solo se puede usar si esta se inyecta. Sin embargo, al mismo tiempo, si una vista RECIBE un ObservableObject, entonces NO DEBE RETENERLO COMO @StateObject puesto que esto causaría que el ciclo de vida del objeto se maneje en dos lugares.


Bibliografía

Top comments (0)