clamp
Clamp
clamp
글쓰기 관리
전체 방문자
오늘
어제
  • 분류 전체보기 (509)
    • IOS (85)
    • SwiftUI+TCA+Combine (9)
    • RxSwift + MVVM (56)
    • Clean Architecture (12)
    • SWIFT (56)
    • iOS - TDD (2)
    • 디자인패턴 (4)
    • CS (56)
      • 알고리즘 (29)
      • 운영체제 (15)
      • 자료구조 (2)
      • 네트워킹 (4)
      • 기타 (6)
    • 회고 (0)
    • Firebase (18)
    • SwiftUI (10)
    • iOS - UIKit (11)
    • iOS - 오픈소스 (6)
    • 코딩테스트 (166)
      • 프로그래머스 (164)
    • 정보처리기사 (14)
    • GitHub (2)
글쓰기 / 관리자

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • uikit
  • Q
  • ㅅ
  • Swift

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
clamp

Clamp

SwiftUI+TCA+Combine

SwiftUI - @ObservableObject, @ObservedObject, @Published, ObjectWillChange

2024. 2. 26. 17:21

@ObservableObject

  • @ObservedObject는 ObservableObject 프로토콜을 준수하는 객체를 관찰하는 뷰 내에서 사용되는 프로퍼티 래퍼입니다.
  • ObservableObject는 Class형태만 가능합니다. Struct형태는 불가능합니다.
  • class의 @Published 인스턴스의 변화를 감지하고 해당 인스턴스가 변화할 때 마다 뷰를 업데이트합니다.
  • ObservableObject 프로토콜을 준수하면 objectWillChange프로퍼티를 사용할 수 있습니다.

* @Published 어노테이션은 값이 변동되었을때 바로 View에게 즉각적으로 알려주는 어노테이션입니다.

 

ex)

class MyViewModel: ObservableObject {
    @Published var score = 0
}

 

struct ContentView: View {
    @ObservedObject var viewModel = MyViewModel()

    var body: some View {
        Text("Score: \(viewModel.score)")
            .onTapGesture {
                viewModel.score += 1
            }
    }
}

 

text의 TapGesture가 발생한경우 ViewModel의 score변수를 +1 증가시키게됩니다.
위 @Published를 사용하지 않았다면 단순히 ViewModel의 score가 +1 되겠지만 @Published이기 때문에 View에 바로 전달되어 +1된 Text가 즉시 업데이트됩니다.

 

* 위에 설명했듯 ObservableObject 프로토콜을 준수하면 objectWillChange프로퍼티를 사용할 수 있습니다.

 

 

ObjectWillChanged

인스턴스 내부 @Published값이 변경될 때 objectWillChange이벤트가 동작합니다.

objectWillChange.send()는 SwiftUI에 값이 변동됐음을 알려주는 메서드입니다.

class ViewModel: ObservableObject {
    var score = 0 {
        willSet(newValue) {
            if score % 3 == 0 {
                objectWillChange.send()
            }
        }
    }
}

 

objectWillChange.send()는 SwiftUI에 값이 변동됐음을 알려주는 메서드라고 설명했듯 @Published가 아니여도 Published처럼 동작하게 만들 수 있습니다.

위의 score메서드는 @Published가 아님에도 objectWillChanged.send()를 직접 호출해줌으로써 SwiftUI에게 값의 변경을 알리고 UI가 업데이트되게됩니다.

 

class MyData: ObservableObject {
  var number: Int {
    willSet { self.objectWillChange.send() }
  }
  
  init(number: Int) {
    self.number = number
  }
}

var data = MyData(number: 20)

data.objectWillChange
  .send()

data.objectWillChange
  .sink { print("change value? = \($0)") }

data.number = 10
data.number = 1


// change value? = ()
// change value? = ()

 

만약 sink를 활용해 구독을 한다고 하면 값의 변경이 일어날 때 sink의 클로저를 실행하게 될것입니다.

 

objectWillChange는 객체의 @Published 프로퍼티 중 하나가 변경되기 전에 방출되는 publisher입니다. 그러나, 이는 실제 변경되는 값을 방출하지 않습니다.

 

@Published

위에 많이 등장했기 때문에 어느정도 감이 잡힐겁니다.

이는 클래스 내의 프로퍼티 앞에 선언되는 프로퍼티 래퍼입니다.

해당 프로퍼티의 값이 변경될 때 마다 구독자(subscriber)에게 알림을 보냅니다.

사용하기 위해선 프로퍼티가 속한 클래스가 Observable프로토콜을 준수해야합니다.

@Published 프로퍼티의 값이 변경되면 이를 관찰하는 SwiftUi 뷰는 자동으로 업데이트됩니다.

저작자표시 비영리 동일조건 (새창열림)
    'SwiftUI+TCA+Combine' 카테고리의 다른 글
    • SwiftUI TCA - 2. 단방향 아키텍처 TCA
    • SwiftUI TCA - 1. TCA의 등장 배경
    • SwftUI - @State, @Binding
    • PropertyWrapper의 projectedValue
    clamp
    clamp
    주니어 iOS개발자의 발악!!!!!!!

    티스토리툴바