250x250
반응형
05-11 19:27
Today
Total
«   2024/05   »
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
Notice
Recent Posts
Recent Comments
Link
Archives
관리 메뉴

Bill Kim's Life...

[RxSwift] Observables(Sequences) : Observables의 기본 개념을 살펴보자 본문

CS(컴퓨터 과학)/RxSwift

[RxSwift] Observables(Sequences) : Observables의 기본 개념을 살펴보자

billnjoyce 2020. 9. 16. 17:17
728x90
반응형
RxSwift의 Observables의 기본 개념에 대해서 살펴봅니다.

 

 

#. 개발 환경

  • Xcode 11.x 이상
  • Swift 5.x 이상
  • RxSwift 5.x 이상

 

 


 

 

Concepts

 

RxSwift의 가장 기본이 되는 개념이자 핵심 철학을 우선 살펴보겠습니다.

 

스마트폰을 예를 들면 스마트폰은 관찰이 가능(observable) 합니다. 스마트폰은 문자메세지 및 전화, 카톡 알림 등과 같이 신호(signal)를 방출 합니다. 우리는 자동적으로 스마트폰을 구독(subscribe)하고 있고, 모든 알림을 홈 스크린 및 앱에서 확인할 수 있습니다. 바로 그런 우리들은 관찰자 (observer) 입니다.

 

이러한 Observable은 일련이 순서(Sequence)를 가지고 있으며 해당 순서대로 구독자한 대상(Observer)에게 이벤트를 전달합니다.

 

특정한 관찰 가능한 대상이 있고 이를 구독하여 일련의 이벤트가 순서대로 발동(emit)되어 각 관찰자에게 전달되는 개념이 바로 Rx가 추구하는 메카니즘(mechanism)이자 기본 프로그래밍 철학입니다.

 

이번 강좌에서는 Observable과 Sequence에 대한 기본적인 개념정도만 살펴보도록 하겠습니다.

 

 

 


 

 

Components

 

RxSwift의 컴포넌트 구성도를 우선 살펴보겠습니다.

RxSwift는 크게 보면 아래와 같이 총 6개의 컴포넌트로 구성되어 있습니다.

 

 

  • RxSwift: RxSwift의 코어 컴포넌트로서 ReactiveX에 의해 정의된 표준 Rx 객체들로 구성되어 있습니다.
  • RxCocoa: 애플의 iOS, macOS, watchOS, tvOS 개발에서 기본이 되는 Cocoa 프레임워크에 대해서 Rx 형태로 랩핑하여 제공하는 컴포넌트입니다.
  • RxRelay: Subjects를 기반으로 랩핑한 PublishRelay 와 BehaviorRelay 객체 등을 제공하는 컴포넌트입니다. 해당 컴포넌트는 RxSwift 컴포넌트의 의존하여 구성됩니다.
  • RxTest and RxBlocking: RxSwift에 의존하여 유닛 테스트 및 통합 테스트 기능을 제공해주는 컴포넌트입니다.

 

 

 


 

 

 

Observable

 

RxSwift의 핵심 객체인 Observable에 대해서 살펴보겠습니다.

 

Rx에서 가장 먼저 이해해야할 사항은 관찰자 패턴 (Observable <Element> 시퀀스)과 일반적인 시퀀스 (Sequence)라는 개념과 동등하다는 부분을 인지하여야 합니다.

 

그로 인하여 모든 Observable 객체는 또하나의 Seqeunce(순서)이며 모든 Observable 흐름은 일련의 순서(Sequence)대로 신호를 방출(emit)하는 것이 기본 핵심 사항입니다. 그러한 순서는 비동기적으로 구독을 하는 대상에게 전달될 수 있으며 선택적으로 특정한 조건에 따라서도 전달될 수 있습니다.

 

기본 Observable 객체의 코드를 보면 아래와 같습니다.

class Observable<Element> {
    func subscribe(_ observer: Observer<Element>) -> Disposable
}

protocol ObserverType {
    func on(_ event: Event<Element>)
}

enum Event<Element>  {
    case next(Element)      // next element of a sequence
    case error(Swift.Error) // sequence failed with error
    case completed          // sequence terminated successfully
}

 

  • Observable(ObservableType)은 Sequence와 동일합니다.
  • Observable은 다양한 타입을 지원하기 위하여 제네릭을 형태를 취하고 있습니다.
  • Observable은 subscribe 메소드는 Sequence의 makeIterator 메소드와 동일합니다.
  • subscribe 연산자를 실행하여야만 구독자가 될 수 있으며 일련의 이벤트를 수신할 수 있습니다.
  • Observable의 이벤트는 기본적으로 next, error, completed 등 세가지의 이벤트가 있습니다.
  • 모든 흐름은 비동기적으로 동작한다.
  • Observable = Observable sequence = Sequence, 모두 다 같은 의미입니다.

 

 

 

 


 

 

 

Sequence

 

아래와 같이 다양한 상황에서의 데이터가 순서(Sequence)대로 전달되는 형태를 볼 수 있습니다.

 

 

  • 1부터 6까지 데이터가 구독자에게 방출(emit)되고 종료되는 형태
--1--2--3--4--5--6--| // terminates normally

 

  • a, b, a, a, a, d 데이터가 전달된 후 에러를 만나서 종료되는 형태
--a--b--a--a--a---d---X // terminates with error

 

  • tap, tap, tap을 불특정한 시간 간격으로 계속 전달되는 형태
---tap-tap-------tap--->

 

다음과 같이 일련의 시간의 흐름 속에서 데이터의 순서(Sequence)를 아래의 그림처럼 표현한 형태를 마블 다이어그램(Marble Diagram)이라고 부릅니다. 

 

 

 

 

 

 

 

 

 

 

 

rxmarbles.com

 

RxMarbles: Interactive diagrams of Rx Observables

 

rxmarbles.com

 

 

다시 한번 Observable 객체의 생명주기를 정리해보면 아래와 같습니다.

 

  1. Observable 객체를 선언하고 데이터 리스트를 입력받습니다.
  2. Observable 객체를 구독하기 위해서는 subscribe를 통하여 구독을 시작합니다.
  3. Observable은 어떤 구성요소를 가지는 next 이벤트를 최신 값을 계속해서 방출할 수 있습니다.
  4. Observable은 error 이벤트를 방출하여 완전 종료될 수 있습니다.
  5. Observable은 complete 이벤트를 방출하여 완전 종료 될 수 있습니다.

 

아래의 코드는 위에서 살펴본 예제 중에서 1부터 6까지의 내용을 구독자에게 전달하고 마무리되는 예제에 대한 소스 코드 예시입니다.

순서(Sequence)대로 1부터 6까지 콘솔에 값이 출력되고 최종 마무리 시에는 onCompleted 이벤트를 발생시키고 마무리되고 있습니다.

 

마지막 부분의 dispose연산자(메소드)는 구독을 취소하고 종료한다는 의미의 역할을 하는 코드입니다.

반드시 모든 순서에 대한 사용 완료 후에는 dispose를 호출하여야 정상적으로 구독 취소와 동시에 메모리가 해제됩니다.

 

// Observable.of 연산자를 통하여 Observable 객체를 생성하고 데이터 리스트를 입력
let subscription = Observable.of(1, 2, 3, 4, 5, 6).subscribe(onNext: {
           print($0) // onNext 이벤트 발생 시마다 해당 데이터 값 콘솔에 출력
       }, onCompleted: {
           print("onCompleted") // onCompleted 이벤트 발생
       })
                
// dispose 함수를 통하여 최종 구독자 객체를 해제                
subscription.dispose()
        
// 1
// 2
// 3
// 4
// 5
// 6
// onCompleted

 

 

 

 


 

 

 

 

Disposing

 

위에서 특정 구독자(Observer)에 대해서 dispose 연산자를 호출하여 정상적으로 구독을 취소하고 메모리 해제를 하는 부분을 살펴보았습니다. 하지만 여러 구독자마다 개별로 일일이 dispose를 호출하는 것은 비효율적일 수 있습니다.

 

따라서 아래와 같이 DisposeBag 라는 객체를 통하여 다수의 구독자들의 구독 종료를 진행할 수 있습니다.

let disposeBag = DisposeBag()
        
let subscription = Observable.of(1, 2, 3, 4, 5, 6).subscribe(onNext: {
   print($0)
}, onCompleted: {
   print("onCompleted")
}).disposed(by: disposeBag)

 

 

 

 


 

 

 

 

Take until

 

추가적으로 takeUntil 이라는 연산자를 통해서도 자동으로 dealloc 이벤트가 발생되기 전까지만 구독을 유지할 수 있습니다.

sequence
    .takeUntil(self.rx.deallocated)
    .subscribe {
        print($0)
    }

 

 

 


 

 

 

이상으로 RxSwift의 Observables의 기본 개념에 대해서 살펴보았습니다.

이번 강좌에서는 Observables와 Sequence에 대한 기본 개념에 대해서만 파악해보았습니다.

 

다음번 강좌에서는 좀 더 구체적인 Observable와 관련하여 다양한 사용 방법 및 연산자(Operator)들에 대해서 살펴보도록 하겠습니다.

 

 

 

감사합니다.

 

 

 

 


[참고 자료(References)]

 

[1] RxSwift: ReactiveX for Swift : github.com/ReactiveX/RxSwiftgithub.com/ReactiveX/RxSwift/blob/master/Documentation/GettingStarted.md

[2] 예제로 시작하는 RxSwift #1 - 기초 : pilgwon.github.io/blog/2017/09/26/RxSwift-By-Examples-1-The-Basics.html

[3] [RxSwift] RxSwift의 기본 개념 - (1) : jinshine.github.io/2019/01/01/RxSwift/1.RxSwift란/
[4] RxSwift 예제로 감잡기 : academy.realm.io/kr/posts/how-to-use-rxswift-with-simple-examples-ios-techtalk/

[5] [Reactive] Reactive Programming 배우는 방법 : mobicon.tistory.com/467

[6] ReactiveX : http://reactivex.io/

[7] RxJS Marbles : rxmarbles.com

728x90
반응형
Comments