1. Subject란?
Subject는 Combine에서 Publisher와 Subscriber 역할을 동시에 수행하는 특수한 타입입니다.
외부에서 직접 값을 전달할 수 있기 때문에, 사용자 입력, 이벤트 트리거, 수동 제어가 필요한 상황에서 많이 사용됩니다.
Combine에서 제공하는 Subject는 2가지
타입 | 설명 |
PassthroughSubject | 현재 값을 저장하지 않고 발행 |
CurrentValueSubject | 하나의 값을 저장하며 새로운 구독자에게 즉시 전달 |
✅ PassthroughSubject 예제
import Combine
let subject = PassthroughSubject<String, Never>()
subject
.sink { print("받은 값:", $0) }
subject.send("Hello") // 출력: 받은 값: Hello
subject.send("World") // 출력: 받은 값: World
- 이전 값을 기억하지 않기 때문에, 구독 이전에 보낸 값은 전달되지 않음
✅ CurrentValueSubject 예제
let subject = CurrentValueSubject<Int, Never>(0)
subject
.sink { print("구독자1:", $0) }
subject.send(1)
subject
.sink { print("구독자2:", $0) } // 구독 즉시 현재 값인 1을 받음
subject.send(2)
- 항상 최신 값을 유지하고 새로운 구독자에게도 바로 전달됨
2. @Published – SwiftUI와의 연결 고리
@Published는 Combine에서 가장 많이 사용되는 Property Wrapper 중 하나입니다.
클래스 내부에서 선언된 프로퍼티에 값이 변경될 때마다 Publisher처럼 동작하며, SwiftUI의 View를 자동으로 갱신하는 데 사용됩니다.
class MyViewModel: ObservableObject {
@Published var username: String = ""
}
@Published는 실제로 내부적으로 이런 Publisher를 가짐
$username: Published<String>.Publisher
이를 통해 외부에서 Combine을 통해 값의 변화를 감지하거나 가공할 수 있습니다.
3. SwiftUI + Combine 연동 예제
import SwiftUI
import Combine
class CounterViewModel: ObservableObject {
@Published var count = 0
private var cancellables = Set<AnyCancellable>()
init() {
$count
.sink { newValue in
print("카운트 변경됨: \(newValue)")
}
.store(in: &cancellables)
}
func increment() {
count += 1
}
}
struct CounterView: View {
@StateObject private var viewModel = CounterViewModel()
var body: some View {
VStack(spacing: 20) {
Text("카운트: \(viewModel.count)")
.font(.largeTitle)
Button("증가하기") {
viewModel.increment()
}
}
.padding()
}
}
✅ 포인트 정리
- @Published로 선언된 count의 값이 바뀌면 SwiftUI가 뷰를 자동으로 갱신
- 내부에서는 Combine의 Publisher처럼 동작하여 sink로 값 추적 가능
- ObservableObject를 사용하면 SwiftUI에서 ViewModel의 변경 사항을 구독할 수 있음
한 눈에 정리
개념 | 설명 |
Subject | 외부에서 직접 값을 발행할 수 있는 Publisher |
PassthroughSubject | 이전 값을 저장하지 않음 |
CurrentValueSubject | 최신 값을 저장하고 새 구독자에게도 즉시 전달 |
@Published | 값이 변경될 때 Combine Publisher로 값 발행 |
SwiftUI 연동 | ObservableObject + @Published로 UI 자동 갱신 가능 |
'Combine' 카테고리의 다른 글
[Combine] 에러 처리: tryMap, catch, replaceError (0) | 2025.04.08 |
---|---|
[Combine] Scheduler와 비동기 처리 이해하기 (0) | 2025.04.08 |
[Combine] Publisher, Subscriber, Operator, Cancellable (0) | 2025.04.07 |
[Combine] Network 통신 (Upbit API 예제 포함) (0) | 2024.11.12 |