ObservableObject Property Wrapper는 ObservableObject프로토콜을 따르는 객체가 필요합니다. 이 프로토콜은 객체의 값이 바뀌기 전에 알려주는 퍼블리셔를 의미하며, SwiftUI가 화면을 다시 그리는 것을 가능하게 합니다.
ObservableObject프로토콜을 따른다면@ObservedObject프로퍼티 래퍼와 함께 SwiftUI 화면에 연결되어 데어터가 변경되었을 때 화면을 다시 그릴 수 있게 됩니다.
예시 코드를 한번 살펴 보겠습니다.
struct ContentView: View {
@ObservedObject private var viewModel = CounterViewModel()
var body: some View {
VStack {
Text("Count \(viewModel.count)")
Button("+") {
viewModel.incrementTapped()
}
Button("-") {
viewModel.decrementTapped()
}
}
.padding()
}
}
final class CounterViewModel: ObservableObject {
@Published var count: Int = 0
func incrementTapped() {
count += 1
}
func decrementTapped() {
count -= 1
}
}
#Preview {
ContentView()
}
위 코드에서는 CounterViewModel 이 ObservableObject 프로토콜을 따르기 때문에 뷰모델을 @ObservedObject로 정의할 수 있었습니다. 뷰모델 내부의 count 값은 버튼을 누를 때마다 증가하게 되고, @Published가 변화했다는 신호를 쏴서 다른 부분에서 변화를 알게 합니다.
조금더 직관적으로 변화하는 과정에대해서 확인해 보겠습니다.
func incrementTapped() {
count += 1
objectWillChange.send()
}
func decrementTapped() {
count -= 1
objectWillChange.send()
}
위 코드를 한번 실행해 보셨다면 동일한 결과를 얻을 수 있다는 것을 알 수 있을 겁니다. 실제로 objectWillChange.send() 메소드를 수동으로 발송해서 이벤트를 발송하는 경우는 거의 없지만 저희는 다양한 케이스를 고려해야 하므로 확인차 보여드렸습니다.
Published 속성래퍼는 변경이 발생했을때 자동으로 알리는 관찰 가능한 오브젝트(Observable Object)를 만들 수 있습니다. SwiftUI는 이러한 변경사항을 자동으로 모니터링하고 데이터에 의존하는 모든 View의 body 속성을 다시 호출 합니다.
실제로
@Published로 표시된 속성이 있는 오브젝트가 변경될때마다 해당 오브젝트를 사용하는 모든 View가 다시 로드되어 해당 변경사항을 반영합니다.
예시 코드를 한번 살펴 보겠습니다.(Not used Published)
final class DataSourceViewModel: ObservableObject {
var items: [String] = []
}
위와 같은 코드는 ObservableObject 프로토콜을 따르고 준수하므로 SwiftUI의 뷰가 변경사항을 감시할 수 있습니다. 그러나 유일한 속성인 items 가 @Published로 표시되어있지 않기 때문에 변경 되었다는 알림(notification)이 전송 되지 않습니다. 물론 objectWillChange.send() 메소드를 사용하여 수동으로 이벤트 발송 할 수 있습니다. 다만 수많은 액션이 있을 경우에 그에 objectWillChange.send() 메소드를 수동으로 이벤트를 발송하게 되면 휴먼에러가 발생 할 수 있다는 단점을 가지고 있습니다. 때문에 @Published를 사용하여 자동으로 이벤트를 감지하는 것이 효율적입니다.
예시 코드(Used Published)
final class DataSourceViewModel: ObservableObject {
@Published var items: [String] = []
}
위와 같은 단점을 보안하기 위해 저희는 @Published 를 사용하여 해당 인스턴스 프로퍼티가 변경 되었을때 자동으로 업데이트를 하여 코드의 가독성도 향상 시킬수 있습니다.