SwiftUI - Published와 ObservedObject

이재원·2024년 7월 9일
0

SwiftUI

목록 보기
4/9
post-thumbnail
post-custom-banner

Published

공식문서를 보면 속성을 게시하는 유형이라고 되어 있습니다.

@propertyWrapper
struct Published<Value>

Published는 SwifUI와 Combine 프레임워크와 함께 사용되는 property wrapper 중 하나로, 프로퍼티를 관찰 가능한 속성으로 만들어주는 역할을 합니다.

@Published를 붙여 만들면 이 유형으로 생성이 가능하고, ObservableObject 프로토콜을 채택한 클래스 내에서만 사용 가능합니다.

또한 $ 오퍼레이터를 붙여 게시자에 엑세스 할 수 있습니다.

class Weather {
    @Published var temperature: Double
    init(temperature: Double) {
        self.temperature = temperature
    }
}

let weather = Weather(temperature: 20)
cancellable = weather.$temperature
    .sink() {
        print ("Temperature now: \($0)")
}
weather.temperature = 25

// Prints:
// Temperature now: 20.0
// Temperature now: 25.0

Weather라는 클래스에 temperature 프로퍼티에 @Published를 붙여 속성 게시 유형으로 만듭니다. 그리고 weather 객체를 만듭니다.

$temperature를 이용해 게시자에 엑세스 할 수 있도록 해줍니다. 그리고 해당 값을 변화시켜주면 출력문이 해당 값에 맞게 출력되게 됩니다

ObservableObject 클래스 내부에서 Published 프로퍼티로 선언된 값이 변경될 때마다 objectWillChange 퍼블리셔가 자동으로 호출시켜 해당 클래스를 관찰 중인 모든 뷰에게 이를 알립니다.

이를 통해 하나하나objectWillChange를 호출하지 않더라도 해당 속성의 값이 변경될 때마다 SwiftUI 뷰에 자동으로 업데이트를 해줍니다.

ObservedObject

공식문서에서는 관찰 가능한 객체를 구독하고 관찰 가능한 객체가 변경될 때마다 뷰를 무효화하는 속성 래펴 유형이라고 되어 있습니다.

이 문장만 봐서는 한번에 이해하기 어려우니 차근차근 알아가 보기를 하며 공석 문서에 있는 정의를 한번 보도록 하겠습니다.

@MainActor @propertyWrapper @preconcurrency @frozen
struct ObservedObject<ObjectType> where ObjectType : ObservableObject

ObservedObject 역시 propertyWrapper인 것을 확인할 수 있습니다. 타입은 ObservableObject 타입에 해당하네요.

ObservableObject는 View 내에서 선언 가능합니다.

ObservableObject를 구독하며 값 업데이트가 발생하면 뷰를 갱신해 줍니다. 따라서 필요한 순간에만 계산되기 때문에 메모리 사용과 처리 시간이 절약됩니다.

class DataModel: ObservableObject {
    @Published var name = "Some Name"
    @Published var isEnabled = false
}

struct MyView: View {
    @StateObject private var model = DataModel()

    var body: some View {
        Text(model.name)
        MySubView(model: model)
    }
}

struct MySubView: View {
    @ObservedObject var model: DataModel

    var body: some View {
        Toggle("Enabled", isOn: $model.isEnabled)
    }
}

MySubView에 @ObservedObject로 DataModel 클래스 타입으로 프로퍼티를 지정해 줍니다.

해당 클래스는 @Published로 name과 isEnabled를 가집니다.

MyView에서 해당 DataModel 타입을 참조하여 프로퍼티를 만듭니다. 그리고 SubView에 해당 프로퍼티를 넘겨주어 연결해줍니다.

그러면 Published로 선언된 name과 isEnabled의 값이 바뀔 때마다 뷰가 바로 갱신되며 보여지게 됩니다.

즉, ObservedObject는 외부 객체의 상태 변화를 관찰하고, 변화가 생길 때마다 뷰를 다시 그리도록 합니다.

ObservedObject의 또 하나의 특징은 해당 객체를 뷰가 소유하지 않는다는 점입니다.

무슨 말이냐면, ObservedObject로 선언된 객체는 해당 객체의 생명 주기를 뷰가 관리하지 않기 때문에 뷰가 사라져도 객체는 유지됩니다.

위 예제를 보면 MySubView에서 ObservedObject로 선언된 model은 DataModel의 변화를 관찰하기는 하지만, DataModel 자체를 소유하지 않습니다.

따라서 DataModel 객체는 MyView가 소유하고 있기 때문에 MyView가 사라지기 전까지는 유효하고, MySubView가 사라져도 DataModel 객체는 여전히 존재합니다.

Published와 ObservedObject 요약

  • Published

    • 속성을 관찰 가능하게 만드는 property wrapper
    • ObservableObject 프로토콜을 채택한 클래스 내에서 사용
    • 값이 변경될 때마다 objectWillChange 퍼블리셔가 자동 호출
  • ObservedObject

    • 외부에서 주입된 ObservableObject를 관찰
    • 값 업데이트 시 뷰를 갱신
    • 객체의 생명 주기를 뷰가 관리하지 않음

마무리

오늘은 Published와 ObservedObject에 대해 익힌 내용을 정리해 봤습니다. 이 글을 읽는 분들 또한 개념이 잘 정리되었으면 좋겠습니다.🙂

출처
https://nsios.tistory.com/120
https://velog.io/@yimkeul/Swift-Published에-대해
https://developer.apple.com/documentation/combine/published
https://developer.apple.com/documentation/swiftui/observedobject
https://green1229.tistory.com/228

profile
20학번 새내기^^(였음..)
post-custom-banner

0개의 댓글