⭐️ Observable
1️⃣ Observable
Reactive X에는 옵저버가 있다.
이 옵저버는 Observable을 구독해서 지켜본다.
Observable이 배출하는 하나 또는 연속된 항목에 옵저버는 반응한다.
이러한 패턴은 동시성 연산을 가능하게 한다.
그 이유는!
Observable이 객체를 배출할 때까지 그 시점을 감시하는 관찰자를 옵저버에 두고,
observable이 객체를 배출하면 관찰자는 옵저버에게 알림을 준다.
위 내용을 마블 다이어 그램으로 요약하면 다음과 같다. (직역 주의)
- 이것은 타임라인이다. / Observable 의 / 시간은 왼쪽에서 오른쪽으로 간다.
- 이것은 아이템들이다. / 생성된 / Observable에 의해
- 이 수직선은 나타낸다. / Observable이 성공적으로 완수했다는 것을.
- 이 점선과 이 박스는 나타낸다. / 변환은 적용된다. / Observable 에 / 박스안에 있는 텍스트는 보여준다. / 변환의 네이처를
- 만약 어떤 이유로 인해 Observable 이 비정상적으로 종료된다면 / 에러와 함께 / 수직선은 X로 대체된다.
- 이 Observable은 / 변환의 결과이다.
2️⃣ 옵저버 생성
ReactiveX 는 기본적으로 비동기와 병렬로 메소드를 호출하지만, Reactive가 아닌 일반적인 메서드 호출은 대개 다음과 같은 흐름으로 진행된다.
// 1. 메서드를 호출한다.
// 2. 메서드가 리턴한 값을 변수에 저장한다.
// 3. 결과 값을 가진 변수를 통해 필요한 연산을 처리한다.
returnVal = someMethod(itsParameters) // 메서드 호출 및 변수에 저장
// 이후 returnVal을 통해 필요한 작업을 진행한다
하지만 비동기 모델에서는 아래와 같은 흐름대로 코드가 실행된다.
// 1. 비동기 메소드 호출로 결과 리턴받고 필요한 동작을 처리하는 메서드를 정의한다.
// 이 메서드는 옵저버의 일부가 된다.
// 2. Observable로 비동기 호출을 정의한다.
// 3. 구독을 통해 옵저버를 Observable 객체에 연결 시킨다.(또한 동시에 Observable의 동작을 초기화
// 한다.)
// 4. 필요한 코드를 계속 구현한다. 메서드 호출로 결과가 리턴될 때마다, 옵저버의 메서드는 리턴 값 또는
// (Observable이 배출하는) 항목들을 사용해서 연산을 시작한다.
// Observable을 정의한다.
Observable.just()
// 옵저버가 Observable을 구독한다.
.subscribe(onNext: { str in
// subscribe에 정의되어있는 옵저버의 onNext 핸들러를 사용한다.
// 코드 구현
})
3️⃣ onNext, onCompleted and onError
onNext : Observable은 새로운 항목들을 배출할 때마다 이 메서드를 호출한다.
onError : Observable은 오류가 발생할 경우 이 메서드를 호출한다.
onCompleted : 오류가 발생하지 않았다면 Observable은 마지막에 onNext를 호출한 후 이 메서드를 호출한다.
⭐️ Disposable
1️⃣ Dispose
disposable.dispose를 하면
실행되고 있는 Observable을 취소시킬 수 있다.
2️⃣ DisposeBag
disposeBag 을 초기화하면서 disposeBag을 지운다.
.dispose(by: disposeBag) 을 이용해서 마지막에 넣을 수 있다.
⭐️ Operators
1️⃣ Just
just()안에 있는 매개변수가 그대로 나오는 연산자
2️⃣ From
배열이 들어간 경우 : 배열에 있는 모든 요소를 한 번씩 뱉어냄
Stream 으로 뱉어낸다.
3️⃣ Map
고차함수에 있는 Map이랑 비슷함.
4️⃣ Filter
고차함수에 있는 Filter랑 비슷함.
9️⃣ 나머지 연산자
reactives.io의 document를 확인해보자.
뭘 써야 할지 모르겠으면 연산자 결정 트리를 확인해라.
연산자 리스트(알파벳순)에 있는 볼드체가 카테고리 목록에 나온 것들임.
⭐️ 마블 다이어그램
Operators 에서 연산자를 누르면 마블 다이어그램으로 넘어갈 수 있다.
구슬 : 데이터
화살표 : 스트림
화살표 쪽 작대기 : complete
파생되는 애들은 RxSwift에 많이 없음 RxJAVA를 봐야 함.
Rxmarbles.com 을 보면 다양한 연산을 확인할 수 있다.
⭐️ Subscribe - Next / Error / Completed
0️⃣ subscribe 와 next, error, completed 란?
Operators로 연산을 다하고 최종적으로 쓸 상황에선 마지막 스트림에 Subscribe를 사용한다.
다른 Operators는 리턴 값이 Stream(Observable)인데 Subscribe은 dispose 이다.
스트림은 Error가 나거나, Completed 되면 종료가 된다.
데이터를 전달받는 게 Next인 이유는 From인 경우 하나씩 전달하기 때문에 next이다.
1️⃣ subscribe()
Observable.just("Hello World")
.subscribe() // 그냥 사라짐
2️⃣ subscribe(on : Event<String>() -> Void)
Observable.just("Hello World")
.subscribe( event in
swift event { // Evnet 타입은 3가지 경우가 있다.
case .next(let str):
break
case .error(let err):
break
case .completed:
break
}
}
3️⃣ subscribe(onNext : …, onError : …, onCompleted : …, onDisposed: …)
Observable.from(["Rx", "in", "4"])
.subscribe(onNext : { s in
...
}, onError: { err in
...
}, onCompleted: {
...
}, onDisposed: { // disposed 된 경우에 실행함,
...
})
.disposed(by: disposeBag)
}
Error도 Dispose를 뱉어내고, Completed도 Dispose를 뱉어냅니다.
이걸 쓰는 경우는 switch 쓰기가 귀찮은 경우, 필요한 것만 사용하고 싶은 경우에 사용한다.
⭐️ Scheduler
0️⃣ 서론
스케줄러를 사용하지 않으면 앞에서 했던 것들이 다 메인 스레드에서 작동할 것이다.
그렇게 되면 UI가 멈추게 될 것이다.
메인 스레드가 아닌 콘커러시 스레드로 옮겨주기 위해 스케줄러를 사용한다.
1️⃣ observeOn()
Obsevable.just("800x600")
.observeOn(ConcurrentDispatchQueueScheduler(qos: .default)) // 이 아래에 있는 코드는 전부다 Concurrent 스레드에서 돌아간다.
.map{...}
.map{...}
.map{...}
.map{...}
.map{...}
.observeOn(MainScheduler.instance) // 이 아래에는 main 스레드에서 돌아간다.
.subscribe() // 세팅하는 곳이 subscribe이니까 subscribe 전에 메인 스레드로 바꿔주야한다.
.disposed(by: ... )
// qos 는 우선순위입니다 ^~^
// <https://tngusmiso.tistory.com/49>
2️⃣ subscribeOn
데이터 가져오는걸 Just에 넣는다면 ObserveOn이 Just에 닿을 수 없다.
그래서 첫 줄부터 스레드를 변경하고 싶다면 SubscribeOn을 사용한다.
SubscribeOn은 아무 데나 넣어도 상관없다.
왜냐하면 subscribe 쓰는 순간 전부다 subscribeOn으로 돌리겠다는 뜻이다.
Obsevable.just("800x600")
.subscribeOn(ConcurrentDispatchQueueScheduler(qos: .default))
.map{...}
.map{...}
.map{...}
.map{...}
.map{...}
.observeOn(MainScheduler.instance) // 이 아래에는 main 스레드에서 돌아간다.
.subscribe() // 세팅하는 곳이 subscribe이니까 subscribe 전에 메인 스레드로 바꿔주야한다.
.disposed(by: ... )
3️⃣ 요약
기본적으로, Observable과 연산자 체인은 이처럼 스케줄러를 통해 동작하고 Subscribe 메서드가 호출되는 스레드를 사용해서 옵저버에게 알림을 보낸다. SubscribeOn 연산자는 다른 스케줄러를 지정해서 Observable이 처리해야 할 연산자들을 실행시킨다. 그리고, ObserveOn 연산자는 Observable이 옵저버에게 알림을 보낼 때 사용할 스케줄러를 명시한다. - ReactiveX.io
https://reactivex.io/documentation/ko/scheduler.html
그리고 Observable은 스트림이기 때문에 subscribeOn으로 첫 스케줄러를 정해줘도 이후 ObserveOn에 의해서 스케줄러가 변경될 수 있다.
4️⃣ 사이드 이펙트
함수 내에서 그치는 게 아니라 외부에 영향을 주는 것을 사이드 이펙트라고 하는데,,,
이 사이드 이펙트를 허용해주는 곳이 2개가 있다.
- Subscribe() : 이미지 뷰 연결하거나 등등…
- do() : 서브스크라입이랑 비슷한데 스트림에서 쓱 지나가면서 사용하는 느낌
Ref
https://www.youtube.com/watch?v=w5Qmie-GbiA&list=PL03rJBlpwTaAh5zfc8KWALc3ADgugJwjq&index=1
'iOS > RxSwift' 카테고리의 다른 글
[iOS] RxSwift - 응용해보기 (0) | 2022.07.23 |
---|