RxSwift - Observables

Seoyoung Lee·2023년 10월 27일
0

RxSwift

목록 보기
2/5


Observable은 RxSwift의 기본이 되는 개념으로, sequence라고도 한다.

예를 들어 iOS 애플리케이션에서 사용자가 탭을 세 번 하면 세 개의 이벤트가 순차적으로 발생될 것이고, 이 이벤트는 언젠가 종료될 것이다.

하지만 어느 순간 에러가 발생해서 이벤트가 완전히 종료되기 전에 프로그램이 종료된다면..??!! 😱

그래서 이벤트들을 구독하자!!는 것이 Observable의 개념이다. Observable을 구독하면 이벤트들의 값이 변할 때마다 이 사실을 알 수 있게 된다.

Observable 써보기

let observable = Observable.just(1)

let observable2 = Observable.of(1, 2, 3) // Observable<Int>

let observable3 = Observable.of([1, 2, 3]) // Observable<[Int]>

let observable4 = Observable.from([1, 2, 3, 4, 5]) // Observable<[Int]>
  • Observable.just() : 하나의 값을 방출할 때 사용
  • Observable.of() : 여러 개의 값을 방출할 때 사용. 여기서 observable2observable3 의 자료형 차이 주목!! observable2는 개별적인 값, observable3은 배열을 저장하고 있음
  • Observable.from() : 하나의 배열을 받아서 배열의 요소들을 순서대로 방출할 때 사용
    • of() 에 배열을 넣으면 배열 자체가 하나의 항목으로 방출되지만, from() 을 사용하면 배열의 요소들이 순서대로 방출된다!!

Subscription 구현해보기

observable4.subscribe { event in
	print(event)
}

Observable을 구독(subscribe)해서 Observable이 가지고 있는 값에 접근할 수 있다.

subscribe 는 실제 값을 가지고 있는 게 아니라 이벤트를 전달해준다. (이벤트, 다음 이벤트, 다음 값, 그 다음 이벤트, 그 다음 값…)

next(1)
next(2)
next(3)
next(4)
next(5)
completed

위 코드를 실행해보면 다음과 같은 결과가 나온다. 실제 저장된 값이 아닌 이벤트가 출력되는 것을 볼 수 있다!

또한 Observable의 모든 값을 출력하고 나면 completed 라는 이벤트가 발생된다.

전 실제 값을 얻고 싶은데요..? 🤔

observable4.subscribe { event in
    if let element = event.element {
        print(element)
    }
}

element 라는 프로퍼티를 사용하면 실제 값에 접근할 수 있다.

observable.subscribe(onNext: { element in
    print(element)
})

위 방법은 옵셔널 언래핑도 해줘야 하고 귀찮으니까..!!! onNext 를 사용하면 더 쉽게 값에 접근할 수 있다.

// 결과
1
2
3
4
5

Disposing and Terminating

subscription을 생성하면 subscriber가 리턴되는데, 이 subscriber는 특정 시퀀스를 관찰(observe)하고 있다.

언젠가 이 subscriber를 사용하지 않게 되면 이 구독을 해제해주어야 한다. 이를 dispose라고 함! 구독을 해제해주지 않으면 메모리 누수 같은 문제가 발생할 수 있기 때문에 꼭 dispose를 해주어야 한다. 🤯

let subscription = observable.subscribe(onNext: { element in
    print(element)
})

subscription.dispose()

dispose() 라는 메소드를 사용해서 dispose를 해줄 수 있다. 하지만 위와 같이 subscription과 dispose를 따로따로 해주면 어느 시점에 dispose를 해줘야 할지 알기 어렵다.

let disposeBag = DisposeBag()

Observable.of("A", "B", "C")
    .subscribe {
        print($0)
    }
    .disposed(by: disposeBag)

그래서 위처럼 subscribe와 disposed 메소드를 이어서 작성해주면 observable가 종료되는 시점에 dispose가 잘 실행될 수 있다.

여기서 DisposeBag 은 이름 그대로 disposable을 담은 가방이다. Dispose 해야 하는 리소스들이 많으면 일일이 dispose() 메소드를 호출해서 구독 해제를 시켜줘야 하는데 너무 귀찮고 번거로우니까!! DisposeBag에 담아주면 이 DisposeBag이 알아서 dispose() 메소드를 호출해준다.

RxSwift) Dispose /Disposable / DisposeBag 이해하기

create로 Observable를 생성하기

Observable<String>.create { observer in
    observer.onNext("A")
    observer.onCompleted()
    observer.onNext("?")
    return Disposables.create()
}.subscribe(onNext: { print($0) }, onError: { print($0) }, onCompleted: { print("Completed") }, onDisposed: { print("Disposed") })
    .disposed(by: disposeBag)

create 메소드를 사용하면 onNext , onCompleted , onError 같은 메소드를 클로저 안에서 직접 호출할 수 있다.

A
Completed
Disposed

이때 onCompleted나 onError가 호출되면 Observable이 dispose 된다. 그래서 위 코드를 실행해보면 onCompleted 다음에 있는 observer.onNext("?") 는 방출이 되지 않는다.

profile
나의 내일은 파래 🐳

0개의 댓글