90 votes

Quelle est la différence entre ObservedObject et StateObject dans SwiftUI

Si j'ai un ObservableObject dans SwiftUI, je peux l'appeler @ObservedObject :

 class ViewModel: ObservableObject {
    @Published var someText = "Hello World!"
}

struct ContentView: View {
    @ObservedObject var viewModel = ViewModel()
    
    var body: some View {
        Text(viewModel.someText)
    }
}

Ou en @StateObject :

 class ViewModel: ObservableObject {
    @Published var someText = "Hello World!"
}

struct ContentView: View {
    @StateObject var viewModel = ViewModel()

    var body: some View {
        Text(viewModel.someText)
    }
}

Mais quelle est la vraie différence entre les deux ? Y a-t-il des situations où l'une est meilleure que l'autre, ou ce sont deux choses complètement différentes ?

8voto

Jacky Points 442

Voici un exemple. Chaque fois que vous cliquez sur le bouton refresh , CountViewObserved force StateObjectClass à être détruit/recréé, de sorte que vous pouvez voir 0 , ce qui n'est pas attendu.

 import SwiftUI
import Combine

class StateObjectClass:ObservableObject{
    let type:String
    let id:Int
    @Published var count = 0
    init(type:String){
        self.type = type
        self.id = Int.random(in: 0...1000)
        print("type:\(type) id:\(id) init")
    }
    deinit {
        print("type:\(type) id:\(id) deinit")
    }
}

struct CountViewState:View{
    @StateObject var state = StateObjectClass(type:"StateObject")
    var body: some View{
        VStack{
            Text("@StateObject count :\(state.count)")
            Button("+1"){
                state.count += 1
            }
        }
    }
}

struct CountViewObserved:View{
    @ObservedObject var state = StateObjectClass(type:"Observed")
    var body: some View{
        VStack{
            Text("@Observed count :\(state.count)")
            Button("+1"){
                state.count += 1
            }
        }
    }
}

struct ContentView: View {
    @State var count = 0
    var body: some View {
        VStack{
            Text("refresh CounterView count :\(count)")
            Button("refresh"){
                count += 1
            }

            CountViewState()
                .padding()

            CountViewObserved()
                .padding()

        }
    }
}

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