✅ 이번 시간에는 Observserbles에 대해서 알아볼 예정이야!
옵저버블 이제 조금 이해가 되기 시작했어. 여기장을 공부할떄는 너무 많아서 이게 과연 가능할까? 까지도 의문이 들더라.. 그래서 일단은 모든 걸 다 해볼 수는 없고, 그림이라도 한번씩 다 봐두면 이해가 되니까 이런 상황에서는 예전에 이런 그림이 있었던 것 같은데...? 하고서 가서 찾아쓰는 방법으로 공부의 방향을 설정했어.
아직 많이 안해서 그런지 여기까지 하니까 rx 뭔가 할만하다...? 이런 생각이 들기 시작했음!!
나의 소스코드 : https://github.com/lgvv/MyRxSwift
http://reactivex.io/documentation/operators.html
https://github.com/lgvv/RxSwiftStudy/blob/main/week2.md
(목차)
1. 이론에 대해서 알아보자
2. emitting? 정확하게 어떤 의미일까?
3. 다시 한번 LifeCycle을 정리해보자
4. operator 입문 (just, from, empty, never, range)
5. 메모리 누수를 막기위해 DisposeBag() 을 사용해보자!
6. 간단한 활용 예시) 버튼 클릭 시에 텍스트 필드에 입력된 정보를 받아오기.
✅ 1. 이론에 대해서 알아보자
Observable은 다양한 이름으로 불려질 수 있다.
✅ 2. emitting? 정확하게 어떤 의미일까?
내가 emitter 쓰면서 이건 onNext? 와 관련하여 순서대로 들어온 데이터가 담기는 장소라고 생각했는데, 이런 의미라고 한다!!
✅ 3. 다시 한번 LifeCycle을 정리해보자
후 라이프 사이클 정말 중요한거 같다. 엄청 자주 보이네!!
✅ 4. operator 입문 (just, from)
여기부터는 아래의 참고자료를 활용해서 작성했어!
- just : 단일 시퀀스로 내려보내줌
- from : 하나하나 따로 내려보내줌
이 두개는 공식문서의 operator 카테고리에서 creating observables에 속해.
이거 말고도 많은 오퍼레이터들이 여기 속하는데, 이건 나중에 따로 포스팅할게..!
그럼 이걸 어떻게 사용하는지도 중요하겠지?
예시에 사용할 부분.
let stringSequence = Observable.just("this is string yo")
let oddSequence = Observable.from([1, 3, 5, 7, 9])
let dictSequence = Observable.from([1:"Rx",2:"Swift"])
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("----stringSequence:just---")
stringSequence.subscribe { (event: Event<String>) in
print(event)
}.disposed(by: disposeBag)
print("----oddSequence:from---")
oddSequence.subscribe { (event: Event<Int>) in
print(event)
}.disposed(by: disposeBag)
print("----dictSequence:from---")
dictSequence.subscribe { (event: Event<(key: Int, value: String)>) in
print(event)
}.disposed(by: disposeBag)
}
이런식으로 사용할 수 있어. 그럼 이거의 결과는 어떻게 나오는지는 조금만 더 내려보자.
여기서 눈에 띄는것은 변수에 옵저버블을 붙여서 사용했다는 것이다.
옵저버블을 붙이면 아무것도 하지 않는데, 그 후에 중요한 작업이 뭐다? subscribe!! 이걸 해줘야 작동을 한다.
그리고 event 타입으로 캐스팅한게 보이는데, 저렇게 캐스팅하면 딕셔너리까지 문제 없이 받을 수 있다.
그럼 딕셔너리나 배열은 just로 받으면? 뭉떵이로 내려오는데, 이러면 사용성이 ㄷ...
✅ 위에가 just와 from이었다면 같은 카테고리의 empty, never, range도 알아보자.
print(" ===== never ===== ")
let neverSequence = Observable<String>.never()
let neverSequenceSubscription = neverSequence
.subscribe { _ in
print("This will never be printed")
}
neverSequenceSubscription.disposed(by: disposeBag)
print(" ===== empty ===== ")
Observable<Int>.empty()
.subscribe { event in
print(event)
}
.disposed(by: disposeBag)
이렇게 작성할 수 있어.
그럼 이거에 대한 결과는 어떻게 나올까?
네버는 절대 실행되지 않고 엠프티는 그래도 컴플릿은 작동되는걸 확인할 수 있어!
그럼 range는 어떻게 쓰이는 것일까?
print(" ===== range ===== ")
Observable.range(start: 1, count: 10)
.subscribe { print($0) }
.disposed(by: disposeBag)
이렇게 사용된다! 마치 for문 같은데 그렇게 어렵지 않습니다!
✅ 5. 메모리 누수를 막기위해 DisposeBag() 을 사용해보자!
week1에서도 설명하고 다른 포스팅에서도 설명했지만, 메모리를 꼭 다시 놔줘야해. rx는 누수가 발생할 확률이 큰데, 우리는 [weak self] 를 통해서 막을 수도 있지만, 이렇게 하면 조금 더 간편해 지겠지?
다만 이것도 단점이 존재해.
네트워크 작업을 비동기로 처리하는데, 중간에 우리가 모종의 이유로 완료되기 전에 취소하게 된거야. 그럼 중단 되어야겠지? 혹은 완료되기 전에 뷰가 dismiss된거야. 이 경우에도 메모리를 그냥 잡고 할게 없이 붕 떠버려. 이렇게 누수가 발생하는데, 이걸 사용해서 viewDidDisAppear에 이걸 실행시키면 자동으로 다 끌고나가서 안전하게 종료 가능!!
직접 subscription.dispose()이렇게!! 하지만 직접 호출하는 것은 bad code smell 이다. Thread가 다를 때 Observable을 사용하기도 전에 메모리를 비워주는 일이 발생할 수 있음.
✅ 6. 간단한 활용 예시) 버튼 클릭 시에 텍스트 필드에 입력된 정보를 받아오기.
여기는 예제 파일을 직접 보면서 쉽게 할 수 있어.
override viewDidLoad() {
button.rx.tap.subscribe(onNext: { next in
self.myJust(element: self.textField.text ?? "null")
.subscribe { s in print(s) }
}).disposed(by: disposeBag)
}
func myJust<E>(element: E) -> Observable<E> {
return Observable.create { observer in
observer.on(.next(element))
observer.on(.completed)
return Disposables.create()
}
}
이 경우에는 이렇게 사용할 수 있어.
(참고)
https://trilliwon.medium.com/rxswift-%EA%B8%B0%EB%B3%B8-%EC%9D%B5%ED%9E%88%EA%B8%B0-1-d4d77ce63ca8
'apple > UIKit & ReactiveX' 카테고리의 다른 글
[week4] Filtering Observables (0) | 2021.07.10 |
---|---|
[week3] Subjects (0) | 2021.07.10 |
🐉 RxSwift(Operators) Creating Observables (0) | 2021.07.09 |
[week1] Hello RxSwift 🖐 (0) | 2021.07.07 |
RxSwift 4시간 만에 끝내기 (0) | 2021.07.06 |