
@StateObject와 @ObservedObject는 관찰중인 객체의 변경에 반응해서 화면을 업데이트할 수 있게 해주는 SwiftUI의 property wrapper 이다. 두 가지 모두 ObservableObject 프로토콜을 따르는 객체를 필요로 하고 겉보기엔 비슷해 보이지만, SwiftUI 어플리케이션을 만들 때 꼭 알아야하는 뚜렷한 차이를 가지고 있다.

위에서 언급했듯, 두 프로퍼티 래퍼 모두 ObservableObject 프로토콜을 따르는 객체를 필요로 한다. 이 프로토콜은 객체의 값이 바뀌기 전에 알려주는 퍼블리셔를 의미하며, SwiftUI가 화면을 다시 그리는 것을 가능하게 한다.
그러니 ObservableObject를 따른다면 @ObservedObject 프로퍼티 래퍼와 함께 SwiftUI 화면에 연결되어 데이터가 변경되었을 때 화면을 다시 그릴 수 있게 된다.
final class CounterViewModel: ObservableObject {
@Published var count = 0
func incrementCounter() {
count += 1
}
}
struct CounterView: View {
@ObservedObject var viewModel = CounterViewModel()
var body: some View {
VStack {
Text("Count is: \(viewModel.count)")
Button("Increment Counter") {
viewModel.incrementCounter()
}
}
}
}
위 코드에선 CounterViewModel이 ObservableObject 프로토콜을 따르기 때문에 뷰모델을 @ObservedObject로 정의할 수 있다. 뷰모델 내부의 count 값은 버튼을 누를 때마다 증가하게 되고, @Published가 변화했다는 신호를 쏴서 다른 부분에서 변화를 알게 한다.

@StateObject 프로퍼티 래퍼는 겉보기엔 @ObservedObject와 비슷하게 작동한다.
struct CounterView: View {
// `@ObservedObject` 대신 `@StateObject`를 사용한 모습
@StateObject var viewModel = CounterViewModel()
var body: some View {
VStack {
Text("Count is: \(viewModel.count)")
Button("Increment Counter") {
viewModel.incrementCounter()
}
}
}
}
하지만 @ObservedObject 대신 @StateObject를 사용하는 것에는 명확한 차이점이 존재한다.
@StateObject를 통해서 관찰되고 있는 객체는 그들을 가지고 있는 화면 구조가 재생성되어도 파괴되지 않는다.
@ObjervedObject는 view를 다시 생성해서 그리지만, @StateObject는 view를 다시 생성하지 않고 항상 동일한 view가 사용@ObservedObject를 쓰는 것은 안전하지 않음@StateObject를 사용하되, 해당 프로퍼티를 subview에게도 주입시켜야 한다면, @ObservedObject로 선언하여 사용할것@StateObject 프로퍼티를 주입하면, 해당 @StateObject의 수명 주기가 두 곳에서 관리가 되므로 의존성을 줄이기 위해 @ObservedObejct를 사용[iOS - SwiftUI] @ObservedObject, @StateObject 개념, 차이점, 사용 방법 (MVVM 패턴)
[수위프트UI/번역] @StateObject와 @ObservedObject, 무엇이 다를까요?