[SwiftUI] Published, ObservableObject

Jenny·2024년 4월 30일

ObservableObject 속성 래퍼(Property Wrapper)

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 속성 래퍼(Property Wrapper)

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 를 사용하여 해당 인스턴스 프로퍼티가 변경 되었을때 자동으로 업데이트를 하여 코드의 가독성도 향상 시킬수 있습니다.

profile
"Jenny 있게 iOS 개발을 하며 대체 불가능한 인재가 되자"

0개의 댓글