티스토리 뷰
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
*/
.create
는escaping
클로저로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
'OpenSource > RxSwift' 카테고리의 다른 글
RxSwift#5 ErrorHandling (0) | 2022.09.28 |
---|---|
RxSwift#4-3 Operators (Combining Operators) (0) | 2022.09.24 |
RxSwift#3 Hot Observable vs Cold Observable, Subjects + Relay (0) | 2022.09.22 |
RxSwift#1 RxSwift의 개념과 용어들 (0) | 2022.09.22 |
RxSwift#4-2 Operators Transforming Operators (0) | 2022.07.18 |