일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- swift 6
- ios
- combinecocoa
- Combine
- swift 5.9
- Subscribe
- SeSAC
- Tuist Swift
- realm
- Subject
- ribs
- Firebase Analytics
- RxSwift
- ios database
- observable
- swift database
- KeyPath
- uitableviewdiffabledatasource
- Firebase
- Swift Tuist
- 카카오뱅크 ios
- GCD
- SwiftUI
- swift db
- JSON
- swift
- 네트워크 통신
- arc
- xcode
- Tuist
- Today
- Total
천원의 개발
RxSwift Observable vs Subject(Publish, Behavior) 차이점 본문
Observable vs Subject
Observable은 이벤트를 방출 하는 역할을 담당하고 Observable을 구독하는 Observer는 이벤트를 받아서 처리 하는 역할을 담당합니다. 그런데 Observable은 새로운 값을 추가 할 수 없습니다. 그래서 새로운 값을 추가 하고 그것을 방출할 수 있는 객체가 바로 Subject입니다.
Subject문서를 확인해 보면 Observable을 상속받고 있으며 ObserverType Protocol을 채택 하는 모습을 확인할 수 있습니다.
그래서 Subject는 Observable의 역할과 Observer 역할을 둘 다 수행할 수 있는 겁니다.
이번에는 ObserverType을 확인해 보면 on 함수가 있는데 이 on함수를 통해서 Observer로 이벤트를 전달할 수 있습니다.
let number = BehaviorSubject<Int>(value: 4)
number
.subscribe { value in
print(value)
} onCompleted: {
print("completed")
}
.disposed(by: disposeBag)
number.on(.next(7)) // on함수를 통해 새로운 이벤트를 observer로 전달합니다.
number.on(.completed)
// 출력
4
7
completed
정리 해보면 결국 Subject는 Observable과 달리 ObserverType을 채택하고 있기 때문에 on 함수를 사용해서 새로운 이벤트를 Observer한테 전달할 수 있는 겁니다.
Unicast Vs Multicas
일반적으로 Observable은 Observer와 Unicast 형태로 동작하는데 예제를 통해 확인 해봅시다.
let num = Observable<Int>.create { observer in // 총 3번이 실행된다
observer.onNext(Int.random(in: 1...100))
return Disposables.create()
}
num.subscribe { value in
print("Observable \(value)") // Observable next(50)
}
.disposed(by: disposeBag)
num.subscribe { value in
print("Observable \(value)") // Observable next(36)
}
.disposed(by: disposeBag)
num.subscribe { value in
print("Observable \(value)") // Observable next(22)
}
.disposed(by: disposeBag)
같은 Observable 이지만 새로 subscribe 할 때 마다 새로운 시퀀스가 생기는 형태입니다. 따라서 subscribe를 여러번 하게 될 경우에는 불필요한 리소스가 발생할 수 있습니다.
반면에 Subject는 Multicast형태로 동작하기 때문에 subscribe를 여러개 해도 하나의 시퀀스를 공유하게 됩니다.
let num = BehaviorSubject<Int>(value: Int.random(in: 1...100)) // 한번 만 실행
num.subscribe { value in
print("Subject \(value)") // Subject next(41)
}
.disposed(by: disposeBag)
num.subscribe { value in
print("Subject \(value)") // Subject next(41)
}
.disposed(by: disposeBag)
num.subscribe { value in
print("Subject \(value)") // Subject next(41)
}
.disposed(by: disposeBag)
PublishSubject
초기값이 없는 상태로 시작합니다.
구독 시점 이후부터 on함수를 통해 전달받은 이벤트를 처리 합니다.
let publish = PublishSubject<Int>() // 초기값이 존재하지 않는다
publish.onNext(1) // on(.next(1)) 이랑 같은형태
publish.onNext(2) // 구독 전에
publish
.subscribe { value in // 구독하기
print("publish -\(value)")
} onError: { error in
print("publish -\(error)")
} onCompleted: {
print("publish - completed")
} onDisposed: {
print("publish - dispose")
}
.disposed(by: disposeBag)
publish.onNext(3) // 구독 후에
publish.onNext(4)
publish.on(.next(5))
publish.onCompleted() // 구독취소
// 출력
publish -3
publish -4
publish -5
publish - completed
publish - dispose
BehaviorSubject
생성시에 초기값을 가지고 시작합니다.
구독 직전의 이벤트를 전달 받습니다.
let behavior = BehaviorSubject<Int>(value: 1)
behavior.onNext(2) // 구독 전에
behavior
.subscribe { value in // 구독하기
print("behavior -\(value)")
} onError: { error in
print("behavior -\(error)")
} onCompleted: {
print("behavior - completed")
} onDisposed: {
print("behavior - dispose")
}
.disposed(by: disposeBag)
behavior.onNext(3) // 구독 후에
behavior.onNext(4)
behavior.on(.next(5))
behavior.onCompleted() // 구독취소
//출력
behavior -2
behavior -3
behavior -4
behavior -5
behavior - completed
behavior - dispose
ReplaySubject
bufferSize에 작성이된 이벤트 만큼, 메모리에 가지고 있다가 구독 직후에 메모리에 저장된 이벤트를 전달 합니다.
let replay = ReplaySubject<Int>.create(bufferSize: 2)
replay.onNext(1)
replay.onNext(2)
replay.onNext(3) // 구독 전에
replay
.subscribe { value in // 구독하기
print("replay -\(value)")
} onError: { error in
print("replay -\(error)")
} onCompleted: {
print("replay - completed")
} onDisposed: {
print("replay - dispose")
}
.disposed(by: disposeBag)
replay.onNext(4) // 구독 후에
replay.onNext(5)
replay.onCompleted() // 구독취소
여기까지 Observable vs Subject 정리였습니다.
공부자료 :
🌱SeSAC iOS 2기 77회차, 78회차
https://sujinnaljin.medium.com/rxswift-subject-99b401e5d2e5
'iOS&Swift🍎 > RxSwift' 카테고리의 다른 글
RxSwift Operator 정리 (0) | 2023.09.11 |
---|---|
RxSwift Subscribe, Bind, Drive 차이점 (0) | 2022.10.28 |
RxSwift 개념 정리 (Observable, Disposable) (0) | 2022.10.26 |