비동기 작업의 결과물을 @escaping completion
으로 콜백 하지 않고, 리턴 값으로 전달해줄 수는 없을까?
- 나중에 생기는 데이터 (Observable)
- 나중에 오면 (subscribe)
event의 종류 (enum)
- .next
- .completed
- .error
순환 참조 막는 방법
:
onNext()
호출 이후에onCompleted()
호출
→ 클로저 사라지면서 Reference Counting 감소
disposable
: subscribe의 리턴값. 동작이 끝나지 않았을 때도 작업을 취소할 수 있음.
: RxSwift 코드를 간단하게 만들어주는 Operator
- 데이터 하나 보낼 때 (Just)
return Observable.just("Hello World")
코드 3줄을 한줄로 만들어줌 👍🏻
return Observable.create { emitter in emitter.onNext("Hello World") emitter.onCompleted() return Disposables.create() }
- 데이터 여러개 차례로 보낼 때 (From)
return Observable.from(["Hello", "World"])
- 실행할 thread 지정 (observeOn)
downloadJson(MEMBER_LIST_URL)
.observeOn(MainScheduler.instance)
.subscribe(onNext: { json in
self.editView.text = json
...
})
아래와 동일한 효과
downloadJson(MEMBER_LIST_URL) .subscribe(onNext: { json in DispatchQueue.main.async { self.editView.text = json ... } })
- subscribe하는 시점의 thread 지정 (subscribeOn)
- Merge
: 여러 Observable(같은 타입) 을 하나로 합쳐준다
- Zip
: 데이터를 쌍으로 보내준다 (타입 달라도 무관)
let jsonObservable = downloadJson(MEMBER_LIST_URL)
let helloObservable = Observable.just("Hello World")
_ = Observable.zip(jsonObservable, helloOberservable) { $1 + "\n" + $0 }
.subscribe(onNext: { json in
self.editView.text = json
...
})
// 실행결과:
Hello World
[json 파일]
- CombineLatest
: 가장 최근의 데이터를 쌍으로 보내준다
- bind
(RxCocoa import 필요)
viewModel.itemsCount
.map { "\($0)" }
.observeOn(MainScheduler.instance)
.bind(to: itemCountLabel.rx.text)
.disposed(by: disposeBag)
코드 3줄을 1줄로 만들어줌 👍🏻
+)weak self
없이 순환 참조 방지 가능viewModel.itemsCount .map { "\($0)" } .observeOn(MainScheduler.instance) .subscirbe(onNext: { [weak self] in self?.itemCountLabel.text = $0 }) .disposed(by: disposeBag)
✅ Table View에 bind
→ TableView DataSource 필요 없어짐!
viewModel.menuObservable
.observeOn(MainScheduler.instance)
.bind(to: tableView.rx.items(cellIdentifier: cellId, cellType: MenuItemTableViewCell.self)) { index, item, cell in
cell.title.text = item.name
cell.price.text = "\(item.price)"
cell.count.text = "\(item.count)"
}
.disposed(by: disposeBag)
- Driver
: UI용 Observable
RxCocoa를 사용해서 UI bind
를 할 때
1) main thread 에서 실행
2) 에러가 발생할 때 리턴할 값 지정
두 가지가 항상 필요한데 driver
가 이 작업을 간단하게 만들어준다.
// driver 사용 X
viewModel.itemsCount
.catchErrorJustReturn("")
.observeOn(MainScheduler.instance)
.bind(to: itemCountLabel.rx.text)
.disposed(by: disposeBag)
// driver 사용 O
viewModel.itemsCount
.asDriver(onErrorJustReturn: "")
.drive(itemCountLabel.rx.text)
.disposed(by: disposeBag)
- Relay
: UI용 Subject (연결이 끊어지지 않음)
accept
(=next)subscribe
의 리턴값인 Disposable
여러개를 하나에 담는 역할.deinit
할 때, 배열에 추가되어있는 disposable
들을 dispose 한다!RxSwift 기능을 UIKit
의 Extension으로 추가한 것
: Observable
처럼 값을 구독할 수 있고, Observable
외부에서 데이터를 주입할 수 있다
: Subject에 누군가 subscribe할 수 있음
: 기본값을 발행한 후, 새로운 데이터가 발생할 때 발행함
: complete 되는 시점에 가장 마지막 데이터를 모든 구독자에게 발행함
: 이때까지 발행된 모든 데이터를 발행 받고 이후에는 PublishSubject와 같이 값을 받음