RxSwift Scan 연산자
Posted on 2021-11-29 by GKSRUDTN99
Swift&Xcode
Swift
RxOperator
RxSwift
RxSwift Scan 연산자
- 이전에 방출된 값과 새롭게 방출되는 값을 이용해 새로운 값을 만들어내는 연산자.
- Collection에서 사용할 수 있는 reduce의 기능과 유사하다.
사용법
Observable.scan('초기값','Accumulator')
의 형태로 사용한다.
-
초기값
- 처음 값이 방출되는 경우 이전에 방출된 값이 없으므로 Parameter로 들어오는 초기값을 이용해 Accumulator를 실행한다.
-
Accumulator
- (previous: T, new: T) -> T 형태의 Closure이다.
- previous에는 이전 계산의 결과값, new에는 새롭게 방출된 값이 들어가게된다.
예제
TextField에 길이제한을 두는 예제
textField.rx.text.orEmpty
.scan("") { [weak self] previous, new -> String in
if new.count > maxCount {
return previous
} else {
return new
}
}
.bind(to: textField.rx.text)
.disposed(by: disposeBag)
-
textField.rx.text
- textField안에 담긴 값을 Observable Stream으로 가져온다.
-
orEmpty
- textField에 값이 없으면 nil을 방출하는데, 이때 nil 대신 빈 문자열("")을 방출하도록 한다.
- 다시말해, Observable
Stream을 Observable Stream으로 바꾼다.
-
scan("")
- 초기값을 빈 문자열로 한다.
-
{ [weak self] previous, new -> String in ~ }
- 처음 값이 방출될 때는 이전 값이 없을 수도 있으므로, previous의 Type은 String?이고, new의 Type은 String이다.
- new의 길이가 maxCount를 넘어가면 새로운 값이 아닌, 이전 값을 TextField에 바인딩하는 코드이다.
의문점
- 위의 예제에서 bind 대신
subscribe(textField.rx.text)
를 사용하면, previous의 타입이 String?으로 잡히는 것을 발견했는데, 자세한 이유는 아직 모르겠다.