@EnvironmentObject란?

2024. 9. 22. 18:57·Category/iOS
728x90

@EnvironmentObject는 SwiftUI에서 뷰 간에 데이터를 공유하는 방법 중 하나로, 전역 상태 관리에 주로 사용됩니다. 이는 뷰의 계층 구조를 따라 상위 뷰에서 하위 뷰로 데이터를 전달하는 방식이며, 상위에서 설정된 객체를 하위에서 자동으로 사용할 수 있게 합니다.

@EnvironmentObject는 앱의 여러 뷰에서 공유되는 데이터를 관리할 때 매우 유용합니다. 예를 들어, 앱 전체에서 상태를 유지해야 하는 사용자 설정이나 세션 정보 등을 공유할 때 사용됩니다.

1. 기본 개념

  • 전역 상태 관리: @EnvironmentObject는 앱의 여러 뷰 간에 전역적으로 상태를 공유하고, 이 상태가 변경될 때 관련된 모든 뷰를 자동으로 업데이트합니다.
  • ObservableObject와 연동: @EnvironmentObject는 내부적으로 ObservableObject와 함께 사용됩니다. 즉, @EnvironmentObject로 지정된 객체는 ObservableObject로 선언되어야 합니다.

2. 사용 방법

  1. ObservableObject 클래스 정의: 먼저 ObservableObject 프로토콜을 채택한 클래스를 정의하고, 해당 클래스의 속성을 @Published로 선언하여 상태 변화를 감지할 수 있게 합니다.
  2. 상위 뷰에서 environmentObject(_:)로 객체를 주입: @EnvironmentObject는 상위 뷰에서 environmentObject(_:)를 통해 주입된 후, 하위 뷰에서 사용할 수 있습니다.
  3. 하위 뷰에서 @EnvironmentObject로 객체를 참조: 하위 뷰에서는 @EnvironmentObject로 선언된 속성을 통해 해당 객체에 접근합니다.

3. 예시

1) ObservableObject 클래스 정의

class UserSettings: ObservableObject {
    @Published var username: String = "Guest"
}

여기서 UserSettings는 사용자의 설정을 관리하는 클래스입니다. username 속성은 @Published로 선언되어 있어, 값이 변경되면 이를 사용하는 모든 뷰가 업데이트됩니다.

2) 상위 뷰에서 환경 객체 설정

struct ContentView: View {
    @StateObject private var userSettings = UserSettings()
    
    var body: some View {
        NavigationStack {
            VStack {
                Text("Current user: \(userSettings.username)")
                NavigationLink("Go to Detail View") {
                    DetailView()
                }
            }
        }
        .environmentObject(userSettings)  // 환경 객체 설정
    }
}
  • @StateObject로 UserSettings 객체를 생성하고, 이 객체를 environmentObject(_:)를 통해 하위 뷰에 전달합니다.
  • environmentObject를 통해 전달된 객체는 하위 뷰에서 자동으로 사용할 수 있습니다.

3) 하위 뷰에서 @EnvironmentObject로 참조

struct DetailView: View {
    @EnvironmentObject var userSettings: UserSettings
    
    var body: some View {
        VStack {
            Text("User: \(userSettings.username)")
            
            Button("Change Username") {
                userSettings.username = "SwiftUI User"
            }
        }
    }
}
  • @EnvironmentObject를 통해 상위 뷰에서 전달된 객체에 접근할 수 있습니다.
  • 버튼을 눌러 username을 변경하면, 상위 뷰와 하위 뷰 모두 자동으로 업데이트됩니다.

동작 설명

  • ContentView에서 userSettings 객체를 환경 객체로 설정하면, DetailView에서 @EnvironmentObject로 해당 객체를 자동으로 사용할 수 있습니다.
  • DetailView에서 username이 변경되면, ContentView에서 이를 사용하고 있는 Text 뷰도 자동으로 업데이트됩니다.

4. @StateObject vs @EnvironmentObject vs @ObservedObject

@StateObject 뷰에서 새로운 객체를 생성하고, 해당 뷰에서만 상태를 관리할 때 사용합니다. 뷰의 라이프사이클과 함께 객체가 유지됩니다. 뷰에서 직접 관리하는 상태가 필요할 때
@ObservedObject 외부에서 전달된 객체를 관찰하고, 상태 변경 시 UI를 업데이트합니다. 객체를 소유하지 않고 참조만 합니다. 객체가 외부에서 전달되고, 해당 객체의 상태를 참조하고 싶을 때
@EnvironmentObject 상위 뷰에서 전역적으로 주입된 상태를 하위 뷰에서 참조하고, 해당 상태가 변경되면 UI를 업데이트합니다. 여러 뷰에서 전역적으로 상태를 공유하고 싶을 때

5. 사용 시 주의사항

  • 상위 뷰에서 반드시 environmentObject(_:)로 객체를 주입해야 합니다. 그렇지 않으면, 하위 뷰에서 @EnvironmentObject로 해당 객체를 참조할 때 앱이 크래시될 수 있습니다.
  • @EnvironmentObject는 뷰 계층 구조에서 데이터를 전파하는 방식이기 때문에, 너무 많은 데이터를 EnvironmentObject로 관리하면 성능 저하나 복잡한 상태 관리 문제가 발생할 수 있습니다.

6. @EnvironmentObject의 장점

  • 전역적인 상태 관리: 여러 뷰 간에 상태를 쉽게 공유할 수 있습니다. 상태를 한 번 설정하면, 뷰 계층 구조 전체에서 재사용할 수 있어 전역 상태 관리에 적합합니다.
  • 간결한 데이터 전파: 부모 뷰에서 자식 뷰로 데이터를 명시적으로 전달할 필요 없이, 부모 뷰에서 설정된 객체를 자식 뷰들이 자연스럽게 참조할 수 있습니다.
  • 자동 UI 업데이트: ObservableObject의 @Published 속성과 함께 사용하면, 상태가 변경될 때 SwiftUI가 자동으로 UI를 업데이트해 줍니다.

결론

@EnvironmentObject는 전역적으로 상태를 관리하고 여러 뷰 간에 데이터를 공유할 때 매우 유용한 도구입니다. SwiftUI에서 앱 전체 또는 큰 뷰 계층에서 데이터를 쉽게 전달하고 관리할 수 있으며, 상태 변화에 따라 UI가 자동으로 업데이트되는 편리함을 제공합니다.

이 개념을 활용하면 복잡한 상태 관리를 더 효율적으로 처리할 수 있으며, SwiftUI의 선언적 UI 방식과 잘 어울리는 방식으로 앱의 전역 상태를 관리할 수 있습니다.

728x90

'Category > iOS' 카테고리의 다른 글

@FocusState란?  (0) 2024.09.23
Identifiable이란?  (0) 2024.09.22
NavigationStack이란?  (1) 2024.09.22
ZStack이란?  (0) 2024.09.22
enum(열거형)이란?  (1) 2024.09.22
'Category/iOS' 카테고리의 다른 글
  • @FocusState란?
  • Identifiable이란?
  • NavigationStack이란?
  • ZStack이란?
Corinee
Corinee
  • Corinee
    Coding Note
    Corinee
  • 전체
    오늘
    어제
    • 분류 전체보기 (361) N
      • Category (354)
        • Algorithm (7)
        • SQL (2)
        • Java (4)
        • C (9)
        • React (7)
        • JavaScript (9)
        • CSS (2)
        • Node (1)
        • SpringBoot (26)
        • Database (3)
        • Network (1)
        • Django (6)
        • Python (22)
        • Flask (4)
        • iOS (25)
        • Swift (4)
        • Flutter (11)
        • Dart (3)
        • Git (1)
        • Firebase (1)
        • Gof (1)
        • 정보처리기사 (112)
        • AI (5)
        • NestJs (4)
        • Docker (1)
        • 사이드 프로젝트 (1)
        • Note (80)
        • Socket (1)
        • 개인 정보 처리 방침 (1)
        • 면접 (0)
        • Vue.js (0)
      • Archive (2) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    원시값(primitive)
    intellij 콘솔 한글 깨짐
    inp
    defaultdict
    chrome extension 자동 배포
    시맨틱 버전(semantic versioning
    named export vs default export
    Jest
    public vs assets
    Collections
    json.parse(json.stringify())
    jackson 라이브러리
    react router
    structuredclone()
    소프트웨어 버전 관리
    프로세스 강제 종료
    stdlib.h
    react
    중첩 함수(nested function)
    useEffect
    mcp server
    x.y.z (메이저.마이너.패치)
    core web vitals
    mermaid-cli
    ajax (asynchronous javascript and xml)
    styled-components
    counter
    semver)
    쉽게 풀어쓴 C언어 Express
    math.h
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Corinee
@EnvironmentObject란?
상단으로

티스토리툴바