[iOS] RxSwift - withUnretained
RxSwift에서의 약한참조
subscribe나 bind를 할때 참조순환을 막기위하여 [weak self] 키워드를 쓰곤 했다.
viewModel.selectedIndex
.subscribe(onNext: { [weak self] _ in
self?.tableView.reloadData()
})
.disposed(by: viewModel.disposeBag)
하지만 RxSwift에서 약한 참조를 선언하는 또 다른 방법이 있었다. RxSwiftExt(RxSwift 에 존재하지 않는 Operator 를 추가한 오픈 소스) 안에 있는 withUnretained라는 메소드인데 RxSwift 는 6 release 부터 withUnretained Operator 를 정식 채택 하였다고 한다.
withUnretained
viewModel.selectedIndex
.withUnretained(self)
.subscribe(onNext: { owner, _ in
owner.tableVIew.reloadData()
})
.disposed(by: viewModel.disposeBag)
이렇게 withUndetained에 매개변수로 self를 넘겨주면 클로저 안에서 원하는 키워드로 self를 약한참조할 수 있다!!
하지만 Error, Completed에 대한 핸들링을 할때는 다시 [weak self] 키워드가 필요하다.
Error / Completed
public enum Event<Element> {
/// Next element is produced.
case next(Element)
/// Sequence terminated with an error.
case error(Swift.Error)
/// Sequence completed successfully.
case completed
}
Next와 Error, Completed는 Event라는 열거형이다. 그 중 Next는 map,flatMap을 통해 우리가 원하는 요소의 유형으로 변경이 가능하지만 Error 와 Completed 는 RxSwift에서 정의해놓은 형식을 따르고있기 때문에 변경이 불가능 하다. 따라서 체인 아래에 있는 Reference 를 subscribe에게 전달할 방법이 없으므로 withUnretained 를 사용할 수가 없다.
subscribe(with:)
viewModel.selectedIndex
.subscribe(with: self) { (owner, _) in
owner.tableVIew.reloadData()
} onError: { (owner, error) in
owner.tableVIew.reloadData()
} onCompleted: { (owner) in
owner.tableVIew.reloadData()
}
.disposed(by: viewModel.disposeBag)
이런식으로 subscribe(with:) 메소드를 사용하여 매개변수로 self를 넘겨주면 원하는 변수(owner)로 약한참조가 가능한 방법이 있다.
댓글남기기