티스토리 뷰

OpenSource/RxSwift

RxSwift#2 Observable

malrang-malrang 2022. 9. 23. 14:11

RxSwift2 Observable

Observable

  • Observable은 이벤트 시퀀스를 비동기적으로 생성하는 기능을 가지고 있다.
  • observable, observable sequence, sequence 모두 같은 말이다.
  • 중요한것은 이 모든 것들이 비동기적()이라는 것 이다.
  • 이 때 Observable이 지속적으로 이벤트를 발생시키는 것을 emit(방출)이라고 한다.

1. Observable의 LifeCycle

  • next를 통해 1, 2, 3을 방출하는 Observable

  • 세번의 tap 이벤트를 방출한뒤 Complete를 통해 종료된 Observable

  • 1, 2를 방출하고 에러가 발생해 error를 통해 종료된 Observable
  • 이전글에 작성한것처럼 여기서 next, error, complete 는 다음과 같다.
    • next: 최신(다음)값을 전송하는 이벤트
    • error: Observable이 값을 방출하다 에러가 발생하면 error를 방출하고 종료시키는 이벤트
    • complete: 성공적으로 이벤트 시퀀스를 종료시키는 이벤트. Observable이 더이상 값을 방출하지 않음.

2. Observable의 생성

.just

let observable: Observable<Int> = Observable<Int>.just(1)
  • just는 오직 하나의 요소를 포함하는 Observable Sequence를 생성한다.

.of

let observables = Observable.of(1, 2, 3)
  • of는 주어진 값들에서 Observable Sequence를 생성한다.
  • 구독하면 1, 2, 3 방출!
let observables = Observable.of([1, 2, 3])
  • of의 인자로 array를 넣게되면 [1, 2, 3]을 단일요소로 가지게 된다.
  • 구독하면 [1, 2, 3] 방출!

.from

let observables3 = Observable.from([1, 2, 3])
  • from은 인자로 array만 넣을수 있다.
  • array 요소들로 Observable Sequence 생성
  • 구독하면 1, 2, 3 방출!

3. Subscribing (구독)

  • Observable은 Sequence의 정의일 뿐이다. Subscribe되기 전에는 아무런 이벤트도 보내지 않는다.
let observable = Observable.of(1, 2, 3)
     observable.subscribe({ (event) in
         print(event)
     })

/* Prints:
      next(1)
      next(2)
      next(3)
      completed
*/
  • 예시 코드를 보면 첫번째 줄에서 Observable<Int>를 생성및 방출하도록 한다.(인자값이 Int값이라 추론해준다!)
  • .subscribe는 escaping 클로저로 Event<Int>를 갖는다. escaping 에 대한 반환값은 없으며 Dispoable을 반환한다.
  • Prints를 보면 observable의 next로 전달된 이벤트를 방출한다.
  • 마지막으로 .completed를 방출한다.

4. subscribe(onNext: , onError:, onCompleted:, onDisposed:)

  • Observable이 방출하는 .next, .error, .completed 각각의 이벤트들에 대해 subscribe 연산자가 있다.
  • 위에서 사용한 subscribe()은 아래와 같이 사용할 수 있다.
Observable.of(1,2,3)
    .subscribe(onNext: { num in
        print(num)
    }, onCompleted: {
        print("completed")
    })
  • 예시 코드에서 onNext 클로저는 next이벤트만을 핸들링하고 나머지는 무시한다.
  • onCompleted 클로저는 completed만 핸들링하고 나머지는 무시한다!

5. 여러가지 Observable

.empty()

let observable = Observable<Void>.empty()

     observable.subscribe(
         onNext: { elem in
             print(elem)
     },
         onCompleted: {
             print("Completed")
     })

 /* Prints:
  Completed
 */
  • empty는 요소를 하나도 가지지 않는 Observable을 생성한다.
  • 따라서 completed이벤트만을 방출하게 된다.
  • 즉시 종료할 수 있는 Observable을 리턴하고 싶을 때 사용한다.

.never()

  • empty와는 반대로 never 오퍼레이터가 있다.
  • let observable = Observable<Any>.never() observable.subscribe( onNext: { element in print(element) }, onCompleted: { print("Completed") } )
  • never 를 사용하면 Completed가 프린트 되지 않는다.

.range()


let observable = Observable<Int>.range(start: 1, count: 10)

 observable
     .subscribe(onNext: { num in
         print(num)
     })
  • range는 start부터 count까지의 값을 갖는 Observable을 생성한다.

6. Disposing

  • 위에 작성한것 처럼 Observable은 subscription(구독)하기 전까진 아무것도 하지 않는다.
  • 즉 subscription이 Observable이 이벤트를 방출하도록 방아쇠 역할을 한다는 의미이다.
  • 따라서 Observable에 대한 구독을 취소함으로써 Observable을 수동적으로 종료시킬 수 있다.

.dispose()

let observable = Observable.of(1, 2, 3)

 let subscription = observable.subscribe({ num in
     print(num)
 })

 subscription.dispose()
  • Int의 Observable을 생성하고 subscribe을 통해 Disposable을 반환한다.
  • 구독을 취소하고 싶다면 dispose()를 호출할수 있다.
  • 현재 observable 안에는 3개의 요소만 있으므로 dispose() 를 호출하지 않아도 Completed가 프린트 되지만, 요소가 무한히 있다면 dispose() 를 호출해야 Completed 가 프린트 된다.

DisposeBag()

  • 각각의 구독에 대해서 일일히 관리하는 것은 효율적이지 못하기 때문에 RxSwift에서 제공하는 DisposeBag을 사용할 수 있다.
  • Disposeable은 DisposeBag instance의 deinit()이 실행될 때 dispose()를 호출한다.
let disposeBag = DisposeBag()

Observable.of(1, 2, 3)
   .subscribe {
       print($0)
   }
   .disposed(by: disposeBag)
  • disposeBag 프로퍼티를 소유하는 인스턴스가 deinit될때 disposeBag 에 담긴 Disposable을 dispose() 해준다!
  • subscribe후 dispose하지 않으면 메모리 누수가 일어나기 때문에 적절한상황에 구독 취소를해주어야한다. 예를 들어 뷰가 deinit될때?

.create(:)

  • Observable을 .create 오퍼레이터로 만드는 방법이 있다.
let disposeBag = DisposeBag()

Observable.create({ (observer) -> Disposable in  
observer.onNext("1")

observer.onCompleted()

observer.onNext("2")

return Disposables.create()  
}).subscribe(onNext: { print($0) },  
onError: { print($0) },  
onCompleted: { print("Completed") },  
onDisposed: { print("Disposed") })  
.disposed(by: disposeBag)

\* Prints:  
1  
Completed  
Disposed  
*/
  • .createescaping 클로저로 AnyObserver<T>를 인자로 받아 Disposable을 반환한다.
  • .next("1"), .completed, .next("2")의 이벤트를 가진 Observable을 생성하고 Disposable을 반환한다.
  • 여기서 .next("2")는 onComplete 이후이기 때문에 방출되지 않는다.

7. Trait

  • Trait은 일반적인 Observable보다 좁은 범위의 Observable이다.
  • Trait을 사용해서 코드 가독성을 높일 수 있다.
  • 종류는 다음과 같다.
    • Single, Maybe, Completable

Single

  • 무한한 이벤트 스트림이 아닌 하나의 결과, 에러를 처리하고자 할 때 사용한다.
  • .success(value) or .error 만을 방출한다.
  • .success(value) 은 .next + .completed
  • HTTP요청 처럼 한번의 응답/에러를 처리할 때 사용한다.

Completable

  • 결과값이 필요하지 않고 완료만 의미 있는 모델에서 사용한다.
  • .completed or .error만을 방출한다.
  • 연산이 성공적으로 완료되었는지 확인하고 싶을때 사용한다.

Maybe

  • Single과 Completable을 섞어 놓은것.
  • .success(value) , .completed , .error 를 방출한다.
  • 하나의 이벤트가 발생하거나, 이벤트 없이 완료 되거나, 에러가 발생하거나 셋 중 하나의 결과를 발생시키고 종료된다.
  • 프로세스가 성공, 실패 여부와 더불어 출력된 값도 내뱉을 수 있을때 사용한다.
  • Observable 을 .asMaybe() 로 변형 가능하다.

참고한 문서및 자료

https://github.com/fimuxd/RxSwift/blob/master/Lectures/02_Observables/Ch2.%20Observables.md
https://okanghoon.medium.com/rxswift-2-observable-subject-relay-8fcd9b01913d

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
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
글 보관함