4 votes

Quelle est la différence entre @State et @ObservedObject, peuvent-ils tous deux être utilisés pour faire persister l'état ?

Lorsque j'ai cherché sur Google "State vs ObservedObject", la première réponse était la suivante résultat venait de Hacking with Swift et il disait à peu près @ObservedObject :

C'est très similaire à @State, sauf que nous utilisons maintenant un type de référence externe plutôt qu'une simple propriété locale comme une chaîne ou un nombre entier.

Puis-je utiliser @ObservedObject pour créer un état persistant ? Est-ce aussi simple que @State est pour les propriétés simples et @ObservedObject est pour les objets complexes ou y a-t-il plus de nuances ?

7voto

Gil Birman Points 9000

@ObservedObject ne persiste pas l'état

Puis-je utiliser @ObservedObject pour créer un état persistant ?

Par lui-même, vous ne pouvez pas. La pomme documentation a ceci à dire sur @State :

Une valeur persistante d'un type donné, par laquelle une vue lit et contrôle la valeur.

Mais je n'ai trouvé aucune mention de la persistance avec @ObservedObject J'ai donc construit cette petite démo qui confirme que @ObservedObject ne fait pas persister l'état :

class Bar: ObservableObject {
  @Published var value: Int

  init(bar: Int) {
    self.value = bar
  }
}

struct ChildView: View {
  let value: Int
  @ObservedObject var bar: Bar = Bar(bar: 0)

  var body: some View {
    VStack(alignment: .trailing) {
      Text("param value: \(value)")
      Text("@ObservedObject bar: \(bar.value)")
      Button("(child) bar.value++") {
        self.bar.value += 1
      }
    }
  }
}

struct ContentView: View {
  @State var value = 0

  var body: some View {
    VStack {
      Spacer()
      Button("(parent) value++") {
        self.value += 1
      }
      ChildView(value: value)
      Spacer()
    }
  }
}

Chaque fois que vous cliquez sur le value++ il en résulte un nouveau rendu de l'image. ChildView parce que le value la propriété a changé. Lorsqu'une vue est rendue à nouveau à la suite d'un changement de propriété, c'est l'inverse qui se produit. @ObservedObject sont réinitialisés

screenshot

En revanche, si vous ajoutez un @State à la variable ChildView vous remarquerez que sa valeur n'est pas réinitialisée lorsque la fonction @ObservedObject est remis à zéro.

Utilisation de l'état persistant avec @ObservedObject

Pour faire persister l'état avec @ObservedObject instancie l'élément concret ObservableObject con @State dans la vue parent. Pour corriger l'exemple précédent, il faudrait donc procéder comme suit :

struct ChildView: View {
  let value: Int
  @ObservedObject var bar: Bar  // <-- passed in by parent view

  var body: some View {
    VStack(alignment: .trailing) {
      Text("param value: \(value)")
      Text("@ObservedObject bar: \(bar.value)")
      Button("(child) bar.value++") {
        self.bar.value += 1
      }
    }
  }
}

struct ContentView: View {
  @State var value = 0
  @State var bar = Bar(bar: 0)  // <-- The ObservableObject

  var body: some View {
    VStack {
      Spacer()
      Button("(parent) value++") {
        self.value += 1
      }
      ChildView(value: value, bar: bar).id(1)
      Spacer()
    }
  }
}

La définition de la classe Bar est inchangé par rapport au premier exemple de code. Et maintenant, nous voyons que la valeur n'est pas réinitialisée même lorsque la fonction value les changements de propriété :

screen shot

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X