본문 바로가기

Swift

[SwiftUI] Property wrappers for data flow

  SwiftUI 는 애플리케이션에서 일어나는 데이터 흐름을 관리하는 몇 가지 도구들을 제공합니다. Swift 5.1 에 추가된 Property wrapper는 변수의 기능을 한 단계 업그레이드 시켜줍니다. SwiftUI 에도 특정한 wrapper가 있습니다. 바로 @State, @Binding, @ObservedObject, @EnvironmentObject 입니다. 이 wrapper들은 변수에 의해 표현된 데이터에 대한 View의 의존성을 선언하는 역할을 합니다. 설명이 너무 어렵나요? 그럼 하나씩 살펴보도록 하겠습니다. 😎

@State

  @State 로 지정된 변수들은 View가 해당 변수들을 소유(own)합니다. 일시적인 것이 아닌 View가 메모리에 살아있는 한, 해당 변수는 메모리에 할당되어 있음을 의미합니다. 그렇기 때문에 이 변수의 값은 꼭 초기화해주어야 합니다. 애플은 이 변수의 접근제어자로 private 을 사용할 것을 권고하고 있습니다. 왜냐하면 @State 변수가 특정 View에 의해 소유되고 관리됨을 강조하기 위함입니다.

@Binding

  @Binding 은 다른 View가 소유하고 있는 @State 변수에 의존성을 선언합니다. View는 @State 변수에 대한 @Binding 을 다른 View에 전달하기 위하여 접두어로 '$'를 사용합니다. 전달받는 View에서는 @Binding 변수가 전달받은 데이터를 참조할 뿐입니다. 그래서 @Binding 변수는 초기값이 필요하지 않습니다. 이 참조를 통해 데이터에 따라 달라지는 View의 상태를 바꿀 수 있습니다.

@ObservedObject

  @ObservedObject 는 참조 타입에 대한 의존성을 선언합니다. 해당 참조 타입은 ObservableObject 프로토콜을 채용해야 합니다. 이 프로토콜은 데이터의 변경사항을 publish 하기위해 objectWillChange 프로퍼티를 가지고 있습니다.

@EnvironmentObject

  @EnvironmentObject 는 shared 데이터에 대한 의존성을 선언합니다. 해당 데이터는 앱의 어떤 View에서도 보여질 수 있는 데이터인 것 입니다. 부모 View에서 자식을 넘어 손자에게 데이터를 전달하고 싶을 때 (특히 자식은 해당 데이터가 필요 없을 경우) 데이터를 간접적으로 전달하기 위한 간편한 방법이기도 합니다.

 

  보통 재사용 가능한 View에서는 @State 변수를 사용하지 않고 @Binding 이나 @ObservedObject 를 대신 사용합니다. View가 해당 데이터를 소유해야만 할 때 @State private var 를 선언하여 사용하면 되는 것입니다.

 

struct ContentView: View {
    @State private var passedValue: String = "Hello World!"
    
    var body: some View {
        Subview(value: $passedValue)
    }
}

struct Subview: View {
    @Binding var value: String

    var body: some View {
        Text($value)
    }
}

 

태그