[새싹 iOS] 19주차_SwiftUI Source of Truth

임승섭·2023년 11월 24일
1

새싹 iOS

목록 보기
35/45

개요

  • 앱에서 UI는 Data에 의존 해서 자신의 상태를 결정한다
    (Data 변경 -> View 갱신)
  • UIKit에서는 Data의 변경 시점마다 UI 업데이트에 대한 모든 코드를 작성해야 한다.
    따라서 Data 변경에 따른 View 관리가 쉽지 않았다.
  • 이러한 불편함을 해소하기 위해 SwiftUI에서는 Source of Truth 를 통해 Data와 UI 사이의 의존 관계 를 만들고,
    Data의 상태가 변하면 body를 rendering 하라는 하나의 의존 관계로 정의하고 있다.

Source of Truth

  • View에서 읽는 모든 Data에는 Source of Truth 가 존재한다 -> @State

  • 메인 화면과 상세 화면의 Data가 동일해야 한다면, 동일한 Data 요소는 한 군데에서 다뤄져야 한다 -> @Binding

    Source of Truth : Derived Value = @State : @Binding

  • SoT는 단일(Single Source of Truth)로 존재해야 하며, 이를 복제하는 것은 상태의 불일치를 일으킬 수 있다.

  • 즉, Data의 변경에 자동으로 UI가 반응하는(의존 관계) SwiftUI에서는 Data에 대한 관리가 중요한데, 단 하나의 데이터 를 다른 뷰에게 전달함으로써 데이터를 여러 곳에서 복사해서 사용하는 사이드이펙트까지 방지할 수 있다.


Property Wrapper

  • 데이터의 일관성을 유지하기 위해, SwiftUI에서는 다음과 같은 Property Wrapper를 사용한다.

1. @State

  • View에서 가지는 Source of Truth로, Data에 대한 상태를 저장하고 관찰한다.

  • 해당 View가 Data를 소유하고 관리한다는 개념을 명시적으로 나타내기 위해 private 접근 제어자를 사용하는 것이 좋다.

  • "상태 프로퍼티" @State
    1. 이 Data는 변할 수 있고, 2. View가 Data에 의존성을 가진다는 것을 의미한다.

  • 즉, Data가 변경이 되면 View도 변경되어야 한다는 의미로, 변경 사항이 감지될 때마다 매번 View를 새로 그려준다.

  • @State를 통해 하나의 Single Source of Truth가 생성된다


2. @Binding

  • 외부에서 Source of Truth를 주입받고 참조받는다.

  • 상위 뷰가 가진 상태를 하위 뷰에서 사용하고 수정할 수 있도록 하는 Derived Value 이다.

  • 값을 읽고 수정하여 다른 뷰에 갱신된 데이터를 전달한다.

  • $ 접두어를 사용하며, 내부적으로 PropertyWrapper의 projectedValue를 이용한다는 것을 의미한다

  • 같은 뷰에서 값을 읽거나 쓰는 경우에는 $ 없이 일반 변수처럼 사용이 가능하다.


3. @Published

  • ObservableObject 프로토콜에서 프로퍼티를 선언할 때 사용되는 property wrapper

  • @Published 로 선언된 프로퍼티의 값이 변경될 때마다 뷰 업데이트

    ObservableObject 프로토콜

    • 클래스에 ObservableObject 프로토콜을 채택하면, 이 프로토콜은 해당 클래스의 인스턴스를 관찰하고 있다가 내부의 @Published 로 선언된 데이터가 변경이 될 때마다 신호를 보내주고, 신호를 받은 뷰는 업데이트된다.

4. @StateObject

  • ObservvableObject 프로토콜을 구독하고 값이 업데이트될 때마다 뷰를 갱신하는 propertywrapper

  • @Published 로 선언된 데이터가 변경될 때의 신호를 받는다

  • @StateObject 로 선언된 인스턴스는 생성 시점에 한 번 초기화되고, 이후 뷰의 렌더링 여부와 상관 없이 @StateObject 로 선언된 변수는 뷰 내에서 재사용된다.


5. @ObservedObject

  • ObservvableObject 프로토콜을 구독하고 값이 업데이트될 때마다 뷰를 갱신하는 propertywrapper

  • @State@Binding의 관계처럼 @StateObject로 선언한 인스턴스를 함께 공유하고 싶을 때 사용한다
    즉, 상위 뷰에서 @StateObject 로 만든 데이터를 하위 뷰에게 전달하고 싶을 때, 데이터를 주입해주면 하위 뷰에서는 인스턴스를 직접 생성하지 않고 전달받아 사용할 수 있다.

  • @ObservedObject 로 선언된 인스턴스는 뷰가 렌더링될 때 인스턴스가 새롭게 생성되기 때문에 기존에 @StateObject로 주입받은 데이터가 휘발될 수 있다.


참고

WWDC : Data Flow Through SwiftUI
SwiftUI) Source of Truth란?

0개의 댓글