원문 : https://www.hackingwithswift.com/quick-start/swiftui/whats-the-difference-between-objectbinding-state-and-environmentobject

@ObjectBinding, @State, @environmentObject 간의 차이점은 무엇인가? (What’s the difference between @ObjectBinding, @State, and @EnvironmentObject?)

State는 모든 최신 앱에서는 사용하며, SwiftUI는 우리의 모든 뷰는 뷰 state의 단순한 함수임을 기억하는 것이 중요합니다 - 우리가 직접 뷰를 변경하지 않지만, 대신 state를 조작하고 그 결과를 나타나게 합니다.

SwiftUI는 우리 앱에서 state를 저장하는 몇가지 방법을 제공하지만, 그것들은 미묘하게 다르고 프레임워크를 적절히 사용하는 것이 어떻게 다른지 이해하는 것이 중요합니다.

지금까지 모든 state 예제들은 @State를 사용해서 다음과 같은 프로퍼티들을 만들었습니다.

struct ContentView : View {
    @State var score = 0
    // more code
}

뷰 안에 프로퍼티를 만들었지만, @State 프로퍼티를 사용해서 SwiftUI에게 메모리 관리를 요청합니다. 이것은 중요합니다: 우리의 모든 뷰는 구조체이며, 이는 변경될수 없다는 의미이고, 만약 게임에서 점수에 1점 추가할 수 없다면 그것은 대단한 게임이 아닙니다.

그래서, @State로 프로퍼티를 만들때, 우리는 제어권을 SwiftUI에게 넘겨줌으로써 뷰가 존재하는 한 메모리에 영구적으로 유지됩니다. state가 변경될때, SwiftUI는 새로운 정보를 반영할 수 있도록 최신 변경사항으로 자동으로 뷰를 다시로딩하는 것을 알고 있습니다.

@State는 특정 뷰에 속하고 뷰 바깥에서는 결코 사용되지 않는 단순한 속성에 좋으므로, 결과적으로 이런 프로퍼티를 다음과 같이 private로 사용하는 것은 좋은 생각입니다.

@State private var score = 0

이는 state가 뷰를 벗어나지 않도록 특별히 설계되었다는 것을 다시 강조합니다. 

@ObjectBinding은 무엇인가요?(What is @ObjectBinding?)

좀 더 복잡한 프로퍼티들에 대해서 - 여러개의 프로퍼티와 메소드를 사용하거나 여러개의 뷰에서 공유할수 있는 사용자정의 타입을 가지고 있을때 - @ObjectBinding을 사용합니다.

이는 문자열(String)이나 정수형(Integer)처럼 단순한 지역 프로퍼티보다는 외부 참조 타입으로 사용되는 것만 제외하면 @State와 매우 비슷합니다. 여러분은 여전히 바뀔 데이터에 달려있다고 말 하지만, 여러분 스스로가 관리할 책임이 있는 데이터임을 제외하면 말입니다. - 클래스 인스턴스로 만들고 자체 프로퍼티를 만드는 등의 작업을 해야 합니다. 

@ObjectBinding으로 사용하는 타입은 BindableObject 프로토콜을 준수해야 하며, 하나의 요구사항이 있습니다: 여러분의 타입은 반드시 데이터가 변경될때 뷰에게 알려주는 didChange 프로퍼티를 구현해야 합니다.

이는 여러분 스스로 관리해야할 책임이 있는 데이터가 있다는 의미입니다 - 여러분의 바인딩된 겍체에 프로퍼티를 설정할때 뷰를 새로고침하도록 강제하거나 그렇지 않은지를 결정할 수 있습니다. 일반적으로 그럴것이지만, 꼭 그렇게해야 할 필요는 없습니다.

bindable 객체는 Combine 프레임워크로부터 publishers를 사용해서 중요한 데이터가 변경되었음을 뷰에 알릴수 있습니다. 만약 bindable 객체가 그 데이터를 사용하는 뷰 여러개를 가지고 있는 경우, 자동으로 모든 뷰에게 알려줄 것입니다. 

경고 : publisher를 사용해서 여러분의 객체가 변경되었음을 알릴때, 반드시 메인 스레드에서 처리해야 합니다.

@EnvironmentObject는 무엇인가?(What is @EnvironmentObject?)

뷰가 변경될때 자동으로 새로 고침하는 단순한 타입의 프로퍼티를 @State으로 선언하는 방법과 뷰가 변경할때 자동으로 새로 고침할수 있거나 그렇지 않을 수 있는 외부 타입의 프로퍼티를 @ObjectBinding으로 선언하는 방법을 살펴봤습니다. 이러한 두가지 모두 여러분의 뷰에 설정해야 하지만, @ObjectBinding은 다른 뷰와 공유될수도 있습니다.

세번째 프로퍼티 타입으로 사용할 수 있는 것은 @EnvironmentObject입니다. 이것은 앱 자체를 통해서 여러분의 뷰에 사용할 수 있는 값입니다 - 모든 뷰가 필요할때 읽을수 있는 공유된 데이터 입니다. 따라서, 여러분의 앱이 모든 뷰가 읽어야할 중요한 모델 데이터가 있는 경우에, 뷰에서 뷰로 전달하거나 그것을 접근 할 수 있는 environment에 넣어둘수가 있습니다.

@EnvironmentObject는 많은 데이터를 앱에 전달해야 할때 엄청난 편의를 봐주는 것으로 생각하세요. 모든 뷰가 동일한 뷰를 바로보기 때문에, 하나의 뷰에서 그 모델을 변경하는 경우 모든 뷰는 즉시 업데이트 합니다 - 앱의 다른 부분이 동기화되지 않을 위험요소는 없습니다.

차이점 요약하기(Summing up the differences)

  • 하나의 뷰에서 단순한 프로퍼티에 @State를 사용합니다. 대부분 private 표시를 합니다.
  • 여러개의 뷰에서 복잡한 프로퍼티에 @ObjectBinding을 사용합니다. 언제든지 참조 타입을 사용할때 @ObjectBinding을 사용해야 합니다.
  • 공유된 데이터 처럼 앱의 다른곳에 만들어진 데이터 프로퍼티에 @EnvironmentObject를 사용합니다.

만약 무엇을 사용해애할지 모르는 경우에, 3가지 중에 @ObjectBinding이 가장 유용하고 가장 일반적으로 사용되는 것을 알게 될것입니다.

Posted by 까칠코더