Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

J

[SwiftUI] @ObservableObject / @Published / @StateObject / @ObservedObject 본문

SwiftUI

[SwiftUI] @ObservableObject / @Published / @StateObject / @ObservedObject

yujaehui 2024. 5. 20. 12:23

`@ObservableObject`, `@Published`, `@StateObject`, `@ObservedObject`는 상태 관리와 데이터 흐름을 위한 속성 래퍼.

이 속성들은 각기 다른 용도로 사용되며, 뷰와 데이터 모델 간의 데이터를 연결하고 상태 변경 시 뷰를 업데이트하는 역할.


1. `@ObservableObject`

정의

  • `@ObservableObject`는 관찰 가능한 객체를 정의하는 데 사용.
  • `ObservableObject` 프로토콜을 채택한 클래스에 적용하며, 해당 객체에서 발생하는 상태 변경을 뷰에 알림.

주요 특징

  1. 클래스에 사용
    • Swift의 `class`에서만 사용할 수 있음.
  2. Publisher 역할
    • `@Published` 속성이 변경되면 `ObservableObject`는 변경 사실을 알림.
  3. Combine의 `@Published`와 함께 사용
    • `@Published`는 `ObservableObject` 내부에서 속성의 변화를 자동으로 퍼블리시.

예제

class CounterViewModel: ObservableObject {
    @Published var count: Int = 0

    func increment() {
        count += 1
    }
}
  • `CounterViewModel`은 `ObservableObject`로 선언되었고, `count` 속성은 `@Published`로 선언되어 변화가 자동으로 퍼블리시.

2. `@Published`

정의

  • `@Published`는 관찰 가능한 프로퍼티를 정의하는 속성 래퍼.
  • `ObservableObject` 내부에서만 사용할 수 있음.

주요 특징

  • Publisher 생성
    • `@Published`는 Combine의 Publisher로 작동하여 상태 변경을 방출.
  • 자동 알림
    • 값이 변경되면 `ObservableObject`를 통해 해당 변경 사항이 자동으로 구독자에게 전달.

예제

class TimerViewModel: ObservableObject {
    @Published var time: String = "00:00"

    func updateTime(to newTime: String) {
        time = newTime
    }
}

3. `@StateObject`

정의

  • 새로운 `ObservableObject`를 소유하는 SwiftUI 뷰에서 사용.
  • 뷰의 라이프사이클 동안 해당 객체를 유지.

주요 특징

  • 소유권
    • `@StateObject`는 SwiftUI 뷰가 객체의 소유권을 가짐.
    • 뷰가 다시 생성되더라도 객체는 동일한 인스턴스를 유지.
  • 초기화 보장
    • SwiftUI 뷰에서 한 번만 초기화.

사용 시기

  • 새로 생성한 객체를 SwiftUI 뷰의 상태로 관리하려는 경우.

예제

struct CounterView: View {
    @StateObject private var viewModel = CounterViewModel()

    var body: some View {
        VStack {
            Text("Count: \\(viewModel.count)")
            Button("Increment") {
                viewModel.increment()
            }
        }
    }
}
  • `@StateObject`는 뷰가 viewModel의 소유권을 가지며, 상태 변경 시 뷰가 업데이트.

4. `@ObservedObject`

정의

  • SwiftUI 뷰가 소유하지 않는 `ObservableObject`를 관찰하는 속성 래퍼.
  • 다른 뷰에서 전달받은 객체를 관찰할 때 사용.

주요 특징

  • 소유권 없음
    • `@ObservedObject`는 객체의 생명주기를 관리하지 않음.
    • 전달된 객체의 상태만 관찰.
  • 데이터 바인딩
    • `@ObservedObject`는 상태 변경을 감지하고 뷰를 업데이트.

사용 시기

  • 부모 뷰에서 자식 뷰로 `ObservableObject`를 전달받아 관찰할 때.

예제

struct ParentView: View {
    @StateObject private var viewModel = CounterViewModel()

    var body: some View {
        DetailView(viewModel: viewModel)
    }
}

struct DetailView: View {
    @ObservedObject var viewModel: CounterViewModel

    var body: some View {
        VStack {
            Text("Detail Count: \\(viewModel.count)")
            Button("Increment") {
                viewModel.increment()
            }
        }
    }
}
  • `ParentView`에서 생성한 `viewModel`을 `DetailView`로 전달하여 관찰하고 상태를 공유.

5. `@StateObject` vs `@ObservedObject`

  `@StateObject` `@ObservedObject`
소유권 뷰가 객체를 소유하며 상태를 관리 객체의 소유권이 없으며 외부에서 전달받아 관찰
라이프사이클 뷰의 생명주기 동안 유지 전달받은 객체의 상태만 관찰
초기화 한 번만 초기화 초기화되지 않으며 전달받아 사용
사용 시기 뷰가 상태 관리 객체를 처음 생성해야 하는 경우 외부에서 전달받은 상태 객체를 관찰해야 하는 경우

6. 정리

  • `@ObservableObject`: 클래스가 상태 변화를 퍼블리시할 수 있도록 정의.
  • `@Published`: `ObservableObject` 내부에서 상태 변경을 퍼블리시.
  • `@StateObject`: 뷰가 `ObservableObject`를 소유하고 상태를 관리.
  • `@ObservedObject`: 외부에서 전달받은 `ObservableObject`를 관찰.

'SwiftUI' 카테고리의 다른 글

[SwiftUI] SwiftUI + TCA : Redux 패턴 영향? 단방향?  (0) 2024.06.30
[SwiftUI] @AppStorage  (0) 2024.05.23
[SwiftUI] @ViewBuilder  (0) 2024.05.20
[SwiftUI] AsyncImage in SwiftUI  (0) 2024.05.13
[SwiftUI] ForEach in SwiftUI  (0) 2024.05.13