[SwiftUI] @StateObject
@StateObject
✅ 아래 공식문서를 바탕으로 작성하였습니다.
https://developer.apple.com/documentation/swiftui/stateobject
특성 선언에 @StateObject 속성을 적용하고 ObservableObject 프로토콜을 준수하는 초기 값을 제공하여 View, App 또는 Scene에서 상태 개체를 만듭니다.
@StateObject var model = DataModel()
SwiftUI에서는 객체를 선언하는 인스턴스에 대해 한 번만 객체의 새 인스턴스를 생성합니다. 관찰 가능한 객체의 속성이 변경되면 SwiftUI는 해당 속성에 의존하는 뷰의 일부를 업데이트합니다.
Text(model.title) // Updates the view any time `title` changes.
우리는 ObservedObject 속성을 이용해서 있는 속성에 state 객체를 전달할 수 있습니다.
다른 방법으로는 environmentObject(_:) modifier를 적용함으로서 뷰의 계층에 환경에 적용할 수 있습니다.
ContentView()
.environmentObject(model)
위의 코드에서 보다시피 만약 environment object를 생성하게 되면 ContentView 안에 있는 객체 또는 그것의 하위 계층에 어디서든 EnvironmentObject 속성을 읽을 수 있습니다.
여기서 잠깐! State와 Binding을 이용한 기법과 environmentObject를 사용하는 것과의 차이를 알아봅시다.
State와 Binding은 주로 1:1 상황에서 유용하다
다만, 하나의 변수가 여러 하위 계층을 건너가야 하는 경우 State와 Binding으로 만들어두면 너무 불편하다.
이 경우에 사용하는 것이 environment이다.
Kuring 프로젝트에서 UIKit을 SwiftUI로 변경할 때 HomeView - NoticeWebView - WebView 이렇게 세가지에서 NoticeModel이 공유되었는데, 이런 경우에 사용하면 BEST!
@EnvironmentObject var model: DataModel
$ 연산자를 사용하여 상태 개체의 속성 중 하나에 대한 @Binding을 가져옵니다. 개체의 속성 중 하나에 대한 양방향 연결을 만들려면 바인딩을 사용하십시오. 예를 들어, 모델에 저장된 isEnabled라는 부울 값을 Toggle이 제어하도록 할 수 있습니다.
Binding에서 상태에 대한 데이터 값을 사용하려면 쉽게 말해서 $ 연산자를 사용해라!!
RxSwift 생각하면 상태를 관찰하려고 구독한다는 느낌!
Toggle("Enabled", isOn: $model.isEnabled)