본문 바로가기
감정일기(가칭)

eraseToAnyPublisher()와 AnyPublisher<[EmotionDiaryModel], Never>)은 Combine에서 가장 헷갈리지만 정말 중요한 개념

by 밤새는 탐험가89 2025. 10. 24.
728x90
SMALL

🧩 1️⃣ AnyPublisher<[EmotionDiaryModel], Never> — 이 타입의 의미부터

AnyPublisher<Output, Failure> 는
Combine의 표준 Publisher 타입을 감싸는 “추상 타입(Wrapper)”이에요.

 

💬 쉽게 말해서:

“이 Publisher는 [EmotionDiaryModel]을 내보내고,
에러는 발생하지 않는다(Never)” 는 뜻이에요.

 

🧠 예를 들어보면

let publisher: AnyPublisher<Int, Never>

 

→ “정수를 계속 emit(방출)할 수 있지만, 실패(Failure)는 절대 발생하지 않는다”

 

Never는 Combine에서 “에러가 발생하지 않는 타입” 을 뜻하는 특별한 타입이에요.
즉, Error의 반대 역할이라고 생각하면 돼요.

 

🧩 그래서 AnyPublisher<[EmotionDiaryModel], Never>는 이렇게 해석돼요:

요소 의미
[EmotionDiaryModel] 일기 데이터 배열을 내보냄
Never 발행 중 에러 발생 가능성 없음
AnyPublisher 내부가 어떤 구체적인 Publisher인지 숨김

 

즉,

"이건 Combine 스트림이지만, 세부 구현은 몰라도 되고
구독만 하면 [EmotionDiaryModel]을 계속 받을 수 있어요"
라는 뜻이에요 ✅


🧩 2️⃣ diariesSubject.eraseToAnyPublisher() 의 이유

diariesSubject는 실제로 이렇게 선언돼 있었죠 👇

private let diariesSubject = CurrentValueSubject<[EmotionDiaryModel], Never>([])

 

즉, 실제 타입은 CurrentValueSubject<[EmotionDiaryModel], Never>예요.
근데 이 타입을 직접 외부에 노출하면 안 돼요.

 

⚠️ 왜냐하면?

CurrentValueSubject는 send() 메서드를 갖고 있어서
외부에서도 값을 강제로 바꿀 수 있기 때문이에요.

store.diariesSubject.send([]) // 😱 외부에서 데이터 변경 가능

 

이러면 ViewModel이 데이터 흐름을 통제할 수 없게 돼요.
→ 즉, SSOT(Single Source of Truth, 단일 데이터 소스) 원칙이 깨져요.

 

💡 그래서 .eraseToAnyPublisher() 를 쓰는 이유는

내부의 구체 타입(CurrentValueSubject)을 감추고,
“읽기 전용”의 추상 타입(AnyPublisher)으로 변환하는 거예요.

var diariesPublisher: AnyPublisher<[EmotionDiaryModel], Never> {
    diariesSubject.eraseToAnyPublisher()
}

 

이렇게 하면 외부에서는 이제 send() 같은 걸 쓸 수 없어요.
오직 sink(구독)만 가능해져요 👇

store.diariesPublisher
    .sink { diaries in
        print("일기 업데이트:", diaries)
    }
    .store(in: &cancellables)

⚖️ 정리하면

구문 역할 비유
diariesSubject 내부 데이터 소스 (실제 값 저장소) “물탱크”
eraseToAnyPublisher() 외부로 노출할 때 보호막 역할 “수도관”
AnyPublisher<[EmotionDiaryModel], Never> 외부에서 볼 수 있는 읽기 전용 Publisher “수돗물만 받을 수 있음 (밸브는 잠겨 있음)”

✅ 최종 한 줄 요약

eraseToAnyPublisher()는 내부의 CurrentValueSubject를
외부에서 수정 못하게 숨기고,
AnyPublisher는 “이건 데이터를 방출만 하는 읽기 전용 스트림”이라는 계약을 뜻한다.

728x90
LIST