RxSwift 기초 문법 공부한 것을 정리하고자 만든 게시물입니다.
부족한 부분이 있다면 꼭 말씀해주세요 😁
이 게시물 역시 참고 용도로 가볍게 봐주시면 감사합니다 😏
RxSwift 기초 문법 🍎
Observable
just
- just 정의로는 "Returns an observable sequence that contains a single element" 라고 되어있다.
- 해석하면 "단일 요소를 포함하는 관찰 가능한 시퀀스를 반환합니다" 라고 한다.
- 쉽게 말해 하나의 요소만 포함하는 Observable Sequence를 생성한다고 보면 된다.
let observable = Observable.just(1)
of
- of 정의로는 "This method creates a new Observable instance with a variable number of elements" 라고 되어있다.
- 해석하면 "이 메서드는 다양한 수의 요소를 가진 새로운 Observable 인스턴스를 생성합니다" 라고 한다.
- 쉽게 말해 여러 개의 요소를 가진 Observable 인스턴스를 생성한다고 보면 된다.
let observable2 = Observable.of(1,2,3) // Int
let observable3 = Observable.of([1,2,3]) // [Int]
from
- from 정의로는 "Converts an array to an observable sequence" 라고 되어있다.
- 해석하면 "배열을 관찰 가능한 시퀀스로 변환" 라고 한다.
- 쉽게 말해 배열 형태의 Observable Sequence를 생성한다고 보면 된다.
let observable4 = Observable.from([1,2,3,4,5])
Subscribe
- Observable에 Observer를 연결하는 접착제
- Observable에서 아이템이 방출, 에러 혹은 완료 알림을 받기 위해서는 반드시 처음에 이 연산자를 Observable에 사용해 구독해야만 가능하다.
Need Unwrapping 📁
- 언래핑이 필요한 경우
let observable = Observable.from([1,2,3,4,5])
observable.subscribe { event in
if let element = event.element {
print("DEBUG: need unwrapping, element is \(element)")
}
}
// DEBUG: need unwrapping, element is 1
// DEBUG: need unwrapping, element is 2
// DEBUG: need unwrapping, element is 3
// DEBUG: need unwrapping, element is 4
// DEBUG: need unwrapping, element is 5
Don't need Unwrapping 📂
- 언래핑이 필요 없는 경우
let observable = Observable.from([1, 2, 3, 4, 5])
observable.subscribe(onNext: { element in
print("DEBUG: need not unwarapping, element is \(element)")
})
// DEBUG: need not unwarapping, element is 1
// DEBUG: need not unwarapping, element is 2
// DEBUG: need not unwarapping, element is 3
// DEBUG: need not unwarapping, element is 4
// DEBUG: need not unwarapping, element is 5
Dispose
- 메모리의 효율성을 위해 구독을 취소하는 메서드
let subscription = observable.subscribe(onNext: { element in
print("DEBUG: element is \(element)")
})
subscription.dispose() // 구독 취소
DisposeBag
- 한 번에 모든 Observer를 지우기 위한 Dispose 가방
- 각각의 비동기 작업들을 DisposeBag에 담아두고 한 번에 처분하는 형식
- 여러 비동기 작업들을 하나씩 관리하기 힘들기 때문!!
let disposeBag = DisposeBag()
Observable.of("A", "B", "C")
.subscribe {
print("DEBUG: value is \($0)")
}.disposed(by: disposeBag)
- When dispose?
- 해당 class가 deinit(메모리 해제)되면 자동으로 해제
Create
- 직접 Observable 시퀀스를 생성할 때 사용
- 포인트는 일회성이기 때문에 반드시 재생성되지 않도록 반환을 해줘야 한다.
Observable<String>.create { observer in
observer.onNext("A")
observer.onCompleted()
observer.onNext("?") // 호출 안됨, onCompleted 선언
// 일회성이기 때문에 반드시 다시 생성되지 않도록 반환하기
return Disposables.create()
}.subscribe {
print("DEBUG: subscribe is \($0)")
} onError: {
print("DEBUG: onError is \($0)")
} onCompleted: {
print("DEBUG: onCompleted")
} onDisposed: {
print("DEBUG: onDisposed")
}
// DEBUG: subscribe is A
// DEBUG: onCompleted
// DEBUG: onDisposed
PublishSubject
- Subscribe한 이후부터 발생하는 이벤트를 처리한다.
let disposeBag = DisposeBag()
let subject = PublishSubject<String>()
subject.onNext("Event 1") // 구독 전이라 Event 1은 출력되지 않는다.
subject.subscribe { event in
print("DEBUG: event is \(event)")
}
subject.onNext("Event 2")
subject.onNext("Event 3")
subject.onCompleted()
subject.dispose()
subject.onNext("Event 4") // Dispose로 인해 더 이상 구독되지 않아 출력 X
// DEBUG: event is next(Event 2)
// DEBUG: event is next(Event 3)
// DEBUG: event is completed
BehaviorSubject
- 초기값을 가지고 생성된다.
- 구독 전 이벤트 중 최신 이벤트만 전달받는다.
let disposeBag = DisposeBag()
let subject = BehaviorSubject(value: "Initial value")
subject.onNext("Start event") // Event 1이 가장 최신이므로 Start event는 전달 X
subject.onNext("Event 1")
subject.subscribe { event in
print("DEBUG: event is \(event)")
}
subject.onNext("Event 2")
subject.onNext("Event 3")
// DEBUG: event is next(Event 1)
// DEBUG: event is next(Event 2)
// DEBUG: event is next(Event 3)
ReplaySubject
- 버퍼의 크기만큼 구독 전 최신 이벤트를 저장하고 있을 수 있다.
let disposeBag = DisposeBag()
//// 버퍼의 크기만큼만 구독 전 최신 이벤트를 전달 받을 수 있다.
let subject = ReplaySubject<String>.create(bufferSize: 2)
subject.onNext("Event 1") // 버퍼 크기가 2이므로, Event 1은 발생 X
subject.onNext("Event 2")
subject.onNext("Event 3")
subject.subscribe { event in
print("DEBUG: event is \(event)")
}
// DEBUG: event is next(Event 2)
// DEBUG: event is next(Event 3)
Relay
- Relay Class는 RxCocoa4에 구현되어있다.
- 클래스로는 PulishRelay와 BehaviorRelay 클래스가 존재한다.
- Subject는 .completed와 .error가 발생하면 종료되지만, Relay는 발생하지 않고, Dispose가 될 때까지 계속 작동한다.
- 이에 UI Event에서 사용하기에 적절하다고 한다.
PublishRelay
- PublishSubject의 Wrapper 클래스로, PublishSubject의 특성처럼 구독 이후의 발생하는 이벤트들만 알 수 있다.
BehaviorRelay
- BehaviorSubject의 Wrapper 클래스로, .value를 통해 현재 값을 가져올 수 있다.
- variable이 Deprecate 되면서 이 BehaviorRelay를 사용하게 된다.
toArray
- 각각 원소가 아닌 배열 자체를 반환받고 싶을 때 사용한다.
let disposeBag = DisposeBag()
Observable.of(1,2,3,4,5)
.toArray()
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
// [1, 2, 3, 4, 5]
let disposeBag = DisposeBag()
Observable.of(1,2,3,4,5)
// .toArray()
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
// 1
// 2
// 3
// 4
// 5
flatMap
- 각각의 요소를 구독할 수 있고, 변경될 때마다 알려준다.
- 리턴에 observable을 반환해준다.
let disposeBag = DisposeBag()
struct Student {
var score: BehaviorRelay<Int>
}
let john = Student(score: BehaviorRelay(value: 75))
let mary = Student(score: BehaviorRelay(value: 95))
let student = PublishSubject<Student>()
student.asObserver()
.flatMap { $0.score.asObservable() }
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
student.onNext(john)
john.score.accept(100)
student.onNext(mary)
mary.score.accept(80)
john.score.accept(59)
// 75
// 100
// 95
// 80
// 59
flatMapLatest
- 가장 최근에 구독한 객체의 요소만 반환해준다.
let disposeBag = DisposeBag()
struct Student {
var score: BehaviorRelay<Int>
}
let john = Student(score: BehaviorRelay(value: 75))
let mary = Student(score: BehaviorRelay(value: 95))
let student = PublishSubject<Student>()
student.asObservable()
.flatMapLatest { $0.score.asObservable() }
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
student.onNext(john)
john.score.accept(100)
student.onNext(mary)
john.score.accept(73) // 무시
mary.score.accept(52)
// 75
// 100
// 95
// 52
'Udemy.zip' 카테고리의 다른 글
[Swift] Firebase 기능 (0) | 2022.03.25 |
---|---|
[Swift]Table View 이슈 (0) | 2022.03.05 |
[Swift]Model 동기화 (0) | 2022.02.27 |
[Swift]ActionSheet-Protocol (0) | 2022.02.25 |