배경
RxSwift?
- 관찰 가능한 시퀀스를 사용해 비동기 및 이벤트 기반 프로그램을 작성하기 위한 라이브러리인 ReactiveX API를 Swift에 적용한 것
- Microsoft에서 제작
핵심 개념
Observer & Observable
- Observable이 값 발행, Observer가 구독 및 관찰 수행
- Observable은 데이터를 방출하는 스트림.
방출 상태
- Observable에서 데이터 방출은 상태와 함께 이루어짐
- onNext: 정상 데이터 방출
- onError: 에러 방출
- onCompleted: 옵저버블 종료 사실 방출.
Disposable & DisposeBag
- 구독을 수행하면 그 반환값은 Disposable 프로토콜을 준수하는 객체
- 이를 DisposeBag 에 담아두면 DisposeBag이 메모리에서 해제될 때 구독의 해제가 함께 일어난다.
DisposeBag을 사용하는 이유
- Observable 객체들은 자신이 살아 있는 동안 이벤트를 방출하지만, Observer 객체는 별도의 참조가 없으면 이벤트를 처리한 뒤 사라질 수 있다.
- Observer 객체가 구독을 유지하기 위해서는 메모리에 남아 있어야 하며, 이를 위해 DisposeBag을 활용한다.
- 또한 더 이상 사용하지 않는 구독은 메모리 누수 방지를 위해 해제가 필요한데, 이 또한 DisposeBag의 deinit 시점에 모두 해제시키기 위해 DisposeBag 사용.
public final class DisposeBag: DisposeBase {
private var lock = SpinLock()
private var disposables = [Disposable]()
private var isDisposed = false
public override init() {
super.init()
}
public func insert(_ disposable: Disposable) {
self._insert(disposable)?.dispose()
}
private func _insert(_ disposable: Disposable) -> Disposable? {
self.lock.performLocked {
if self.isDisposed {
return disposable
}
self.disposables.append(disposable)
return nil
}
}
private func dispose() {
let oldDisposables = self._dispose()
for disposable in oldDisposables {
disposable.dispose()
}
}
private func _dispose() -> [Disposable] {
self.lock.performLocked {
let disposables = self.disposables
self.disposables.removeAll(keepingCapacity: false)
self.isDisposed = true
return disposables
}
}
deinit {
self.dispose()
}
}
- 따라서 구현을 살펴보면 DisposeBag이 deinit 되는 시점에 참조하고 있던 모든 disposable을 메모리에서 해제하는 로직을 확인할 수 있다.
Cold & Hot Observable
- 구독을 해야 데이터가 방출되기 시작하는 옵저버블은 Cold
- 구독과 무관하게 데이터가 방출되는 옵저버블은 Hot
Operator
- 마블 다이어그램 참고
- map, zip, merge, flatMap 등 여러 오퍼레이터 숙지
Scheduler
- Swift의 DispatchQueue와 의미가 동일
- RxSwift에서 작업을 수행할 때 어떤 스레드에서 수행할 지 지정하는 장치
- 참고
subscribeOn & observeOn
- subscribeOn : Observable의 작업이 어느 스케줄러에서 수행될지 결정
- observeOn : Observer가 Observable을 어느 스케줄러에서 관찰할지 결정

Subject
- Observable과 Observer의 역할을 모두 수행 가능한 객체
- BehaviorSubject -> 초기값 있음
- PublishSubject -> 초기값 없음
- Behavior -> 현재 상태를 의미. 현재 상태를 방출
- Publish -> 새로운 이벤트 발행을 의미. 새로운 값을 방출
Relay
- 에러나 완료 이벤트를 방출하지 않게 설계된 RxCocoa의 Subject
- 주로 UI 이벤트에서 사용(UI를 그리는 작업은 멈추지 않아야 하기 때문)
- 마찬가지로 BehaviorRelay, PublishRelay 있음
RxCocoa
- Swift 언어가 아닌 iOS, macOS 등 프레임워크에 대해 Rx 프로그래밍을 지원하는 도구
- UI 관련 작업에 대해 반응형 프로그래밍이 가능해진다.
출처
https://github.com/ReactiveX/RxSwift
https://reactivex.io/