본문 바로가기

iOS/SwiftUI

@StateObject vs @ObservedObject 차이

반응형

 

SwiftUI에서 @StateObject vs @ObservedObject 차이에 대해 알아보쟈.

 

 

둘 다 뷰가 ViewModel을 구독하기 위해 사용하는 프로퍼티 래퍼지만, 

언제 어떤 걸 써야 할까 ? 

 

❓ @StateObject

- 목적 : 뷰에서 ViewModel을 생성하고 소유할 때 사용.

- 메모리 관리 : View가 ViewModel의 라이프사이클을 책임짐

- 주 용도 : 최초 생성 뷰 (루트 view)

- 생성 타이밍 : 뷰가 생성될 때 ViewModel을 같이 생성 

 

struct ContentView: View {
    @StateObject var viewModel = ToDoViewModel() // 여기서 생성!

    var body: some View {
        // ...
    }
}

👉 뷰가 사라질 때까지 ViewModel이 유지됨.

 

❓ @ObservedObject

- 목적 : 이미 생성된 ViewModel을 관찰할 때 사용

- 메모리 관리 : ViewModel의 라이프사이클을 책임지지 않음

- 주 용도 : 부모로부터 주입 받는 경우 (서브 뷰)

- 생성 타이밍 : ViewModel은 외부에서 주입됨

 

struct DetailView: View {
    @ObservedObject var viewModel: ToDoViewModel // 주입받음

    var body: some View {
        // ...
    }
}

👉 ViewModel의 라이프사이클은 부모 뷰가 관리하고, 나는 그냥 ‘관찰’만 하는 입장.

 

 

 

  • @StateObject 👉 "내가 ViewModel 만든다!" (소유권 O)
  • @ObservedObject 👉 "부모가 만든 ViewModel 쓸게요!" (소유권 X)

 

 

+++ 추가 )

✅ @EnvironmentObject란?

@EnvironmentObject는 앱 전역 또는 여러 뷰에서 공유할 수 있는 ViewModel을 주입하는 방법

  • 전역적으로 공유하는 ViewModel을 사용할 때 적합.
  • 부모 → 자식 → 손자까지 데이터가 명시적 파라미터 전달 없이 바로 접근 가능.
  • 보통 앱 진입 시 WindowGroup에서 .environmentObject로 주입.
  • 생성 위치 : App, 상위 뷰
  • 주 사용 시점 : 앱 전체 / 여러 뷰에서 공유할 때
  • 전달방법 : .environmentObject로 주입

 

 

🔍 언제 사용할까 ? 

  • 로그인 상태, 사용자 설정, 장바구니 등 앱 전역 상태가 필요할 때.
  • 너무 많은 뷰를 거쳐서 @ObservedObject로 전달하기 번거로울 때.

 

1. ViewModel

import Foundation

class UserSettings: ObservableObject {
    @Published var username: String = "Guest"
}

 

 

2. App 진입점에서 주입

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(UserSettings()) // 여기에 주입
        }
    }
}

 

3. 뷰에서 사용

import SwiftUI

struct ContentView: View {
    @EnvironmentObject var settings: UserSettings // 바로 접근

    var body: some View {
        VStack {
            Text("Hello, \(settings.username)")
            Button("Change Username") {
                settings.username = "SwiftUser"
            }
        }
    }
}
반응형