ReactiveX의 Swift 라이브러리인 RxSwift의 핵심 구성 요소는 Observable과 이를 구독하여 이벤트를 처리하는 Observer이다.
| Observer Pattern https://refactoring.guru/design-patterns/observer |
|---|
![]() |
![]() |
ObservableObservable은 데이터를 방출하는 스트림이다. (시간 개념)

Observable은 데이터를 비동기적으로 생성하고 방출한다. 데이터는 이벤트로 표현되며, onNext, onError, onCompleted 세 가지 유형이 있다.
Observable 생성Observable.createObservable.create는 개발자가 커스텀하게 이벤트를 정의할 수 있도록 제공한다.
import RxSwift
let customObservable = Observable<String>.create { observer in
observer.onNext("Hello")
observer.onNext("RxSwift")
observer.onCompleted() // 스트림 종료
return Disposables.create()
}
customObservable.subscribe(
onNext: { print("onNext:", $0) },
onError: { print("onError:", $0) },
onCompleted: { print("onCompleted") },
onDisposed: { print("onDisposed") }
)
Observable.just하나의 값을 방출하는 Observable을 생성한다.
let observable = Observable.just("Single Value")
observable.subscribe(onNext: { print($0) })
Observable.of여러 값을 순차적으로 방출하는 Observable을 생성한다.
let observable = Observable.of(1, 2, 3, 4, 5)
observable.subscribe(onNext: { print($0) })
Observable.from배열과 같은 Sequence로부터 순차적으로 방출하는 Observable을 생성한다.
let numbers = [1, 2, 3, 4, 5]
let observable = Observable.from(numbers)
observable.subscribe(onNext: { print($0) })
Observable.interval지정한 시간 간격으로 값을 방출한다. 주로 타이머나 반복 작업에 사용된다.
let observable = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
observable.subscribe(onNext: { print($0) }).disposed(by: DisposeBag())
subscribesubscribe는 Observable을 구독하여 이벤트를 처리하는 메서드이다. 주로 onNext, onError, onCompleted 핸들러를 정의한다.
let observable = Observable.of(1, 2, 3)
observable.subscribe(
onNext: { print("onNext:", $0) },
onError: { print("onError:", $0) },
onCompleted: { print("onCompleted") }
)
let coldObservable = Observable.from([1, 2, 3])
coldObservable.subscribe { print($0) }let subject = PublishSubject<String>()
subject.onNext("Hot") // 구독 전에 방출된 데이터는 받을 수 없음
subject.subscribe { print($0) }
subject.onNext("Observable")DisposeBagRxSwift의 메모리 관리를 위해 사용하며, 구독을 명시적으로 해제하지 않아도 DisposeBag이 해당 구독을 자동으로 해제한다.
기본적으로 구독 후에는 disposed(by: disposeBag) 을 호출해서 구독 해제를 명시해야 한다.
subscribe 를 수행하면 Disposable 객체가 되고, 이를 DisposeBag 안에 담으면 DisposeBag 이 메모리에서 해제될 때 구독의 해제가 함께 일어난다.
let disposeBag = DisposeBag()
Observable.of("Rx", "Swift")
.subscribe { print($0) }
.disposed(by: disposeBag)
.disposed(by:)를 호출하지 않았는데도 onDisposed가 출력되는 이유는 subscribe로 생성된 Disposable 객체가 구독이 끝나거나 오류가 발생했을 때 자동으로 해제(dispose)되기 때문입니다.
Observable의 생명주기Observable은 onNext, onError, 또는 onCompleted 이벤트 중 하나가 발생하면 구독이 종료된다.Disposable도 자동으로 해제된다. 따라서 명시적으로 .disposed(by:)를 사용하지 않아도 onDisposed는 호출된다.onDisposed의 호출 시점:onDisposed는 Observable의 구독이 종료될 때 호출된다.onError 이벤트가 발생할 때onCompleted 이벤트가 발생할 때dispose()를 호출할 때.disposed(by:)를 사용하지 않아도 Observable의 생명주기가 끝나면 자동으로 onDisposed가 호출된다. 하지만, 명시적으로 메모리 관리를 하고 싶거나, 구독이 무한히 지속될 수 있는 상황에서는 .disposed(by:)를 사용하는 것이 필수적이다.
Trait는 Observable의 특수한 형태로, 단일 이벤트나 특정 이벤트 흐름을 명확히 표현하기 위해 사용된다.
Single단 하나의 값 또는 에러를 방출한다.
하나의 값을 방출하거나, 에러를 방출하면 곧바로 스트림이 종료된다.
( onSuccess, onFailure )
let single = Single<String>.create { single in
single(.success("Single Success"))
return Disposables.create()
}
single.subscribe { event in
switch event {
case .success(let value):
print("Success:", value)
case .failure(let error):
print("Error:", error)
}
}
Maybe값을 방출하거나, 방출하지 않고 완료하거나, 에러를 방출할 수 있다.
( onSuccess, onError, onCompleted )
let maybe = Maybe<String>.create { maybe in
maybe(.success("Maybe Value"))
maybe(.completed) // 값을 방출하지 않을 수도 있음
return Disposables.create()
}
maybe.subscribe { event in
switch event {
case .success(let value):
print("Success:", value)
case .completed:
print("Completed")
case .failure(let error):
print("Error:", error)
}
}
Completable값을 방출하지 않고 완료하거나 에러를 방출한다.
( onCompleted, onError )
let completable = Completable.create { completable in
completable(.completed)
return Disposables.create()
}
completable.subscribe {
print("Completed")
} onError: { error in
print("Error:", error)
}