[ios / swift] @State, @Binding, @ObservableObject

2022. 12. 27. 00:55IOS

 

 

요즘 swiftUI를 사용하여 ios개발을 공부하고 있는 데 중간중간 등장하는 @State와 @Binding 에 대해 궁금증이 생겨 정리해보게 되었다!

 

@State

기존에 UIKit 에서는 어떤 변수의 값이 바뀌면, 변화한 값을 직접 반영을 해주어야 했고 그러기 위해 적절한 위치에서 관찰을 해 주었어야 했다. 하지만 swiftUI에서는 @State라는 property wrapper를 이용해 이 과정을 자동화할 수 있다. 다음과 같이 변수를 선언할 때 @State를 붙여주면 된다. @State로 선언이 되었다면, 해당 인스턴스는 그 값이 아닌 값을 읽고 쓰는 것을 의미하게 된다.

@State var isToggleOn: Bool = true

 

반영되는 방식은 해당 View를 없애고 바뀐 값에 맞추어 새로 VIew를 만든다. 다시 말해 View에서 값만 바꾸는 것이 아니라 View 자체를 바꾸어 버린다.

 

마지막으로 @State는 현재 뷰 UI의 특정 상태를 저장하기 위해 만들어졌다. 따라서 보통 private이랑 같이 쓰이며, 다른 뷰에서 이 값을 사용하고 싶다면 @Binding을 사용해야 줄 수 있다.

 

 

 

@Binding

다른 뷰에서 @State 로 선언된 속성을 사용하고 싶다면 @Binding 속성을 사용해야 한다. 그래야 @State로 선언된 속성에 변화가 생겼을 때 @Binding 변수가 이를 인지해 해당 뷰에 변화를 반영할 수 있다. 해당 속성 사용시에는 Binding변수임을 나타내기 위해 앞에 "$"를 붙여 사용해야한다. 

 

 

 

@ObservableObject, @Published

위의 @State와 @Binding은 View안에서 사용된다. @ObservableObject 는 View가 아닌 class에서 사용된다는 점에서 차이점이 존재한다. 사용법 또한 간단하다.

 

반영이 자동으로 되길 원하는 속성이 들어있는 클래스를 선언할 때에 ObservableObject를 상속해주고 해당 속성에 @Published 를 붙여 준 뒤에 해당 클래스의 인스턴스를 만들 때 @ObservableObject 을 붙여주면 된다.

import SwiftUI

class CountClass: ObservableObject {
    @Published var count: Int = 0
}

struct CountEx: View {
    @ObservedObject var CountInstance = CountClass()

    var body: some View {
        VStack(spacing: 20) {
            Text("\(CountInstance.count)").font(.title)
            Button {
                CountInstance.count += 1
            } label: {
                Text("count++")
            }
        }

    }
}

struct CountEx_Previews: PreviewProvider {
    static var previews: some View {
        CountEx()
    }
}