SwiftUI - Singleton, @EnvironmentObject

ChangJun Lee·2024년 1월 5일
1
post-custom-banner

Singleton 패턴

class의 단일 인스턴스를 전체에서 공유할 수 있도록 하는 디자인 패턴으로,
한개만 생성해서 전역에 두고 해당 Instance에만 접근하도록 하는 것.

// 클래스 
final class ProductStore: ObservableObject {
    static let shared = ProductStore() 
    private init() {}    
    
    @Published var products = [Product]()
    ...
}

클래스는 상속하지 않을 것으로 final 을 붙여서 성능을 올리고,
init() 은 외부에서 접근하여 초기화 경우가 없도록 private 을 붙여주었습니다.

// SwiftUI 의 View 에서 사용 코드
struct ProductListView: View {
    @ObservedObject private var productStore = ProductStore.shared
    
    var body: some View {
        VStack {
        	...
        }
    }
}

위 코드처럼 static 프로퍼티를 사용하면, ProductStore를 싱글톤으로 접근 할 수 있다.

Singleton 의 장단점

하나의 인스턴스를 전역으로 가지고 있기 때문에,
메모리를 낭비하지 않고 공통된 객체로 공유를 편하게 할 수 있다는 장점이 있다.

하지만, 전역에서 아무렇게나 사용될 위험이 있고 ( 의존성 ↑ ),
위 코드에서 init()에 private을 붙여주었기에 생성이 제한되어 테스트에 어려움을 겪기도 한다.
또한, 멀티 쓰레드의 환경에서 싱글톤 객체가 2개가 생기는 위험이 있을 수 있다.


@EnvironmentObject

SwiftUI 에서 많은 뷰와 데이터를 공유할 때, 사용하게 되는 Attribute. ( ObservableObject 를 위한 속성 )

주입해 준 뷰의 하위 뷰라면, 어디든 사용가능하다.
보통 User 를 관리하는 객체를 사용한다.
( 최상위 뷰에서 주입을 해준다면 로그인 여부, 이름 등 앱의 전역에서 확인 할 수 있으니..! )
Singleton 오브젝트와 비슷하게 생각하면 될 것 같다.

// 클래스 
final class ProductStore: ObservableObject {
    @Published var products = [Product]()
    ...
}

따로 static 값을 만들어줄 필요가 없음.

// 상위 View 에서 environmentObject 인스턴스 주입
@main
struct ProductTestApp: App {    
    var body: some Scene {
        WindowGroup {
            ProductListView()
                .environmentObject(ProductStore())
        }
    }
}
// SwiftUI 의 View 에서 사용 코드
struct ProductListView: View {
    @EnvironmentObject private var productStore: ProductStore
    
    var body: some View {
        VStack {
        	...
        }
    }
}

@EnvironmentObject 로 받아서 사용. 타입만 선언.

profile
iOS Developer
post-custom-banner

0개의 댓글