RxSwift를 왜 사용해야 할까?
Notification, Delegate Pattern, Closure, 옵저버 패턴으로도 반응형 프로그래밍을 구현할 수 있으나, 다음과 같은 장점이 있다.!
1. Thread 처리가 쉽다.
- MainThread 에서 처리하기, 백그라운드에서 처리하다 다시 메인, 다시 백그라운드, .. 쉽게 처리할 수 있다.
- 코드가 깔끔해진다.
- 가독성이 좋다.
- 비동기 이벤트의 흐름을 쉽게 파악하고 작성할 수 있다.
- RxSwift를 사용하지 않는다면 여러 스레드간의 클로저 이벤트 처리나 콜백지옥으로 코드가 복잡하고 가독성이 떨어질 수 있다.
- MVVM Design Pattern과 같이 사용하여 이벤트 중심 프로그램에서 데이터의 바인딩을 쉽게 처리할 수 있다.
- Operator를 사용하여 이벤트들을 연산할 수 있다.
- 연속된 escaping closure를 피할 수 있다.
public func subscribe (
onNext: ((Element) -> Void)? = nil,
onError: ((Swift.Error) -> Void)? = nil,
onCompleted: (() -> Void)? = nil,
onDisposed: (() -> Void)? = nil
) -> Disposable
let disposable = button.rx
.tap
.subscribe(onNext: {})
diebutton.rx
.tap
.subscribe(onNext: { disposable.dispose() })
Observable<Int>.interval(
.seconds(1),
scheduler: MainScheduler.instance
)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
단 1개의 항목(item)만 방출하는 Observable Sequence를 생성합니다.
파라미터로 Observer를 매개변수로 받는 클로저를 전달받는 Observable Sequence를 생성합니다.
매개변수로 받은 Observer의 onNext, onCompleted, onError 메서드를 직접 호출할 수 있습니다. 클로저가 끝나기 전에 반드시 onCompleted이나 onError를 정확히 1번 호출해야 하며, 그 이후로는 Observer의 다른 어떤 메서드도 호출해선 안됩니다
let subject = PublishSubject<String>()
subject.subscribe(onNext: {
print("첫번째 Observer가 받는 항목 : \($0)")
}).disposed(by: disposeBag)
subject.onNext("1")
subject.onNext("2")
subject.subscribe(onNext: {
print("두번째 Observer가 받는 항목 : \($0)")
}).disposed(by: disposeBag)
subject.onNext("3")
let subject = BehaviorSubject<Int>(value: 1)
subject.subscribe(onNext: {
print("첫번째 Observer가 받는 항목 : \($0)")
}).disposed(by: disposeBag)
tf.rx.text
.observe(on: MainScheduler.instance)
.subscribe(with: self , onNext: { ( _ , str ) in
self.lb.text = str
}).disposed(by: disposBag)
tf.rx.text
.bind(to: lb.rx.text)
.disposed(by: disposBag)
이처럼 UI를 Controll 하는데 있어 Rxcocoa 를 사용하는것이 조금더 우위에 있습니다. (가독성 등에도 차이가 있는듯 하다).
또한 값을 주입하기 때문에 순환참조에서도 벗어날수 있습니다.
bind 는 binder 되어 있는 Property의 값을 전달받아 주입하기 때문에 따로 메모리릭에 대비하지 않아도 됩니다.
예를 들어 sizeToFit을 rx에서 사용하고 싶다면
extension Reactive where Base: UIView {
var sizeToFit: Binder<Void> {
return Binder(base) { base, _ in
base.sizeToFit()
}
}
}
다음과 같이 extension을 작성하여
button.rx.sizeToFit()
이렇게 사용할 수 있습니다.
참고 자료
RxSwift 4시간 끝내기 : https://www.youtube.com/watch?v=iHKBNYMWd5I&t=8s
RxSwift 정리 블로그 : https://babbab2.tistory.com/182
RxCocoa 정리 블로그 : https://velog.io/@leejinseong9410/RxSwift-RxCocoa