iOS 응용 (SwiftUI)

[iOS - SwiftUI] @StateObject 사용 주의 사항 (Accessing StateObject's object without being installed on a View. This will create a new instance each time.)

jake-kim 2024. 9. 20. 01:51

@StateObject 사용하다 보는 주의 메시지

  • StateObject의 객체에 접근하다보면 가끔 뷰 install되기 전에 StateObject의 객체 접근하여 매번 새로운 인스턴스가 생성된다는 문구가 등장

  • 전체 코드는 아래와 같고, 이 원인 제공은 바로 @StateObject로 선언한 object의 값을 변경할 때 발생
@main
struct ExStateObjectApp: App {
    var contentView = ContentView()
    
    var body: some Scene {
        WindowGroup {
            contentView
                .onAppear {
                    contentView.changeAge()
                }
        }
    }
}

class MyObject: ObservableObject {
    @Published var age = 0
}

struct ContentView: View {
    @StateObject var object = MyObject()
    
    var body: some View {
        VStack {
            Text("age: \(object.age)")
        }
        .padding()
    }
    
    func changeAge() {
        object.age = 1
    }
}
  • 발생 지점은 ContentView의 changeAge() 메서드
  • 실제로 object.age = 1을해도 변경되지 않음

age = 1을 했음에도 변경되지 않음

에러의 정체

Accessing StateObject's object without being installed on a View. 
This will create a new instance each time.
  • @StateObject를 선언한다는 의미는 해당 뷰에서 이 인스턴스의 라이프사이클은 해당 뷰에서 결정한다는 의미
    • @StateObject를 선언된 곳 외부에서 호출하면 해당 뷰 라이프사이클 외부에서 호출한 것이므로 경고 메시지가 표출되는 것
  • 그렇다면 @StateObject의 사용처는?

@StateObject 사용처

  • 상위 뷰와 하위 뷰가 있을 때, 상위 뷰에서 어떤 상태도 변경시키지 않고 하위 뷰에서만 변경하는 경우, 상위 뷰에서 @StateObject로 선언하고 하위 뷰에서 @ObservedObject로 선언하여 사용

* 읽어보면 좋은 글

- @StateObject vs @ObservedObject (#ViewModel, 뷰 상태관리)

- @StateObject, @EnvironmentObject, @ObservedObject 때에 맞게 사용하기

 

* 참고

- https://www.mattmoriarity.com/2020-07-03-stateobject-and-observableobject-in-swiftui/?trk=public_post_comment-text