[RxSwift] Observable

Judy·2023년 2월 20일
0

RxSwift

목록 보기
1/6
post-thumbnail

fimuxd/RxSwift를 참고해 정리하는 글입니다 🙂

Observable

Observable이란?

  • observer는 Observable을 구독(subscribe)
  • observer는 Observable이 방출(emit)하는 모든 item이나 시퀀스에 반응
  • 작업이 완료될 때까지 기다리지 않고 모든 작업을 진행할 수 있음

⇒ 비동기적으로 진행

Observable의 생명주기

Event

1) onNext

  • 데이터를 전달
  • Observable이 항목을 내보낼 때마다 이 메서드를 호출

2) onCompleted

  • 이벤트를 성공적으로 종료
  • 마지막 onNext 이후 이 메서드를 호출

3) onError

  • Observable이 에러를 발생했고 종료
  • 이 메서드를 호출해 데이터 생성에 실패했거나 다른 오류를 알림
  • 이후 onNext 또는 onCompleted를 호출하지 않고 종료
public enum Event<Element> {
 	/// Next elemet is produced.
 	case next(Element)
 	
 	/// Sequence terminated with an error.
 	case error(Swift.Error)
 	
 	/// Sequence completed successfully.
 	case completed
 }

Observable의 생명주기

  1. 생성 - create()
  2. subscribe() -> subscribe해야 함수 내부가 실행됨
  3. onNext로 데이터 전달
    ---끝---
  4. onCompleted로 종료 / 또는 onError로 종료
  5. Disposed

❗️ 한 번 끝난 observable은 다시 사용할 수 없음, 새롭게 subscribe해줘야 함

Observable 만들기

1. just

  • 하나의 요소를 포함하는 Observable sequence를 생성
  • 하나의 데이터만 보내고 끝
let observable:Observable<Int> = Observable<Int>.just(1)
// 1

2. of

let one = 1
let two = 2
****let observable2 = Observable.of(one, two, three)
// 1 -> 2 -> 3
  • 주어진 데이터의 타입을 추론해서 Observable sequence를 생성

3. from

  • from 연산자는 오직 array 만  가능
  • 배열 형태로 넣으면 element를 하나씩 방출
let observable3 = Observable.from([1, 2, 3])
// 1 -> 2 -> 3

4. Range

  • 범위의 시작과 길이를 선택하는 일련의 정수 범위를 순서대로 방출

5. empty()

  • 요소를 가지지 않은 경우 empty() 를 통해 completed 만 방출
let observable = Observable<Void>.empty()
  • 즉시 종료할 수 있는 Observable을 또는 0개의 값을 가지는 Observable을 리턴하고 싶을 때 사용

6. never()

  • empty() 와 다르게 onCompleted 조차 방출하지 않음
  • do 를 이용해 처리

7. create

  • 데이터를 보내고, 에러를 보내고, 컴플리트 처리
Observable<Int>.create { observer in 
    observer.onNext(1)
    observer.onCompleted()
    
    return Disposables.create()
}

Observable 구독

1. subscribe()

  • Observable은 subscribe하기 전에는 아무런 이벤트도 보내지 않음
  • subscribe를 통해 이벤트 값을 전달받음
let observable = Observable.from([1, 2, 3])

observable.subscribe { (event) in 
		print(event)
}

// next(1)
// next(2)
// next(2)
// completed
  • 각 element를 next 로 방출하고 최종적으로 completed 방출
  • .subscribe은  Disposable을 리턴

2. subscribe(onNext:)

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

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

// 1
// 2
// 3
  • subscribe(onNext:) 를 이용하면 .next 의 이벤트 값만 받을 수 있다
  • 이와 비슷하게 onError , onCompleted 도 처리

Disposing과 종료

1. dispose()

  • subscribe 로 Observable을 구독한다면 dispose 로 구독을 취소
// Observable 정의
let observable = Observable.of("A", "B", "C")
     
// Observable 구독
let subscription = observable.subscribe({ (event) in
         
// eventt 처리
		print(event)
})

// Observable 구독 취소 
subscription.dispose(
  • dispose 한 이후에는 더 이상 방출되지 않음
  • 요소가 무한한 경우 dispose 를 호출해야 completed

2.DisposeBag()

  • 각 구독을 일일이 관리하는건 비효율적이라 DisposeBag()을 활용
  • DisposeBag()disposable을 담고 있음
let disposeBag = DisposeBag() // DisposeBag 생성
     
Observable.of("A", "B", "C")
 .subscribe { 
  print($0)
}
	.disposed(by: disposeBag) // subscribe로 생성된 disposable를 DisposeBag에 담음
  • DisposeBag이 할당 해제할 때마다 dispose()를 호출
  • dispose()를 해주지 않는다면 메모리 누수가 발생할 수 있음

Create

let disposeBag = DisposeBag()
     
Observable<String>.create({ (emitter) -> Disposable in
		// "1" 방출
		emitter.onNext("1")

		// observer.onError(MyError.anError)
		// 종료
		emitter.onCompleted()
         
		// ?
		emitter.onNext("?")
         
		// Disposable 생성 및 리턴
		return Disposables.create()
})
  • escaping 클로저로 AnyObserver를 취한 뒤 Disposable을 리턴
  • AnyObserver는 generic 타입으로 Observable sequence에 값을 추가할 수 있고 해당 값은 subscriber 에 방출된다
  • ? 부분은 이미 onCompleted로 종료된 이후라 방출되지 않음
  • 만약 중간에 onError를 한다면 에러를 통해 종료됨
  • onCompletedonError로 종료하지 않고 disposeBag에도 넣지 않으면 메모리 낭비가 발생

defer

  • subscriber에게 새롭게 Observable을 방출할 수 있는 생성 방법
let deferredObservable: Observable<Int> = Observable.deferred {
		flip = !flip
         
		if flip {
				return Observable.of(1,2,3)
		} else {
				return Observable.of(4,5,6)
		}
}
  • subscribe시 flip에 따라서 다른 event를 방출

Traits

  • Trait은 일반적인 Observable 보다 좁은 범위의 Observable 으로 선택적으로 사용

1. Single

  • .success(value) 또는 .error 이벤트를 방출
  • .success(value) = .next + .completed
  • 성공 또는 실패로 확인될 수 있는 1회성 프로세스
  • ex) 다운로드, 디스크 로딩

2. Completable

  • .completed또는 .error만을 방출하며, 이 외 어떠한 값도 방출하지 않음
  • 연산이 제대로 완료되었는지만 확인하고 싶을 때
  • ex) 파일 쓰기

3. Maybe

  • Single + Completable
  • success(value).completed.error를 모두 방출
  • 프로세스가 성공, 실패 여부와 더불어 출력된 값도 방출하고 싶을 때

do

  • 작업중인 Observable에 영향을 주지 않고 별도의 작업을 수행할 수 있는 연산자
  • 다양한 수명 주기 이벤트에 대해 수행할 작업을 등록

debug

  • Observable의 모든 event를 출력하는 연산자
  • ex) subscribed, isDisposed ..

RxSwift_Study

profile
iOS Developer

0개의 댓글