ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RxSwift - take, takeWhile, takeUntil에 대해서 알아보자.
    Ray Wenderlich/RxSwift 2018. 4. 5. 01:17

    Ch5. Filtering Operators(3) p.112 - p.118


    이전 Ch5 포스트에서는 ignore, elementAt, filter, skip, skipWhile, skipUntil 을 살펴보았다.

    Filtering Operators(1)은 여기를 클릭

    Filtering Operators(2)은 여기를 클릭


    이번 포스트에서는 take, takeWhile, takeUntil, distinctUntilChanged에 대해서 알아보자.


    Taking operators

    take(_:)

    take는 skip의 정반대 개념이다. skip은 처음 발생하는 n개의 이벤트를 무시하는 기능이었다면, take는 처음 발생하는 n개의 이벤트만 받고 나머지는 무시한다.

    그림으로 살펴보자.

    take(2)의 역할은 아주 명백하다. 처음 발생한 2개의 이벤트만 받고 나머지는 무시하고 있다.


    코드를 통해 알아보자.

    1. [1, 2, 3, 4, 5, 6] 총 6개의 이벤트를 발생시킨다.

    2. 하지만 첫 3개의 이벤트만 전달될 것이다.

    로그는 어떻게 찍힐까?



    takeWhile(_:)

    takeWhile은 skipWhile과 유사하다. takeWhile에는 클로져가 전달되고, 이 클로져는 이벤트의 Element를 검사한다.

    검사를 통과한 이벤트는 전달될 것이다. 

    만약에 검사를 통과하지 못한 이벤트가 있다면?? 그 이벤트는 물론이고 그 이후의 모든 이벤트가 무시된다.


    그림을 통해 살펴보자.

    클로져를 보니 3보다 작은 값들만 시킬 것 같다. 1, 2는 무사 통과!!

    그리고 클로져를 만족시키지 못하는 3이 등장했다. 3과 그 이후 모든 이벤트가 무시될 것이다.


    코드는 생략

    코드가 궁금하시면 댓글 부탁드려요 :)


    takeUntil(_:)

    takeUntilskipUntil과 유사하다.

    takeUntil Operator에는 두 개의 시퀀스가 등장한다.

    데이터 스트림을 발생시키는 시퀀스와, trigger의 역할을 하는 시퀀스다.


    이해를 돕기 위해 그림을 보자.

    맨 위에 있는 시퀀스에서 1, 2, 3의 이벤트가 발생하고 있고, takeUntil이 걸려있다.

    그 아래에 있는 시퀀스는 Trigger역할을 하는 시퀀스다. 두 번째 이벤트(초록색 2)가 발생한 뒤 Trigger 시퀀스에 .next이벤트가 발생했다.

    그 이후에 발생하는 모든 이벤트는 무시된다. 그래서 3도 무시되었다.


    코드를 통해 살펴보자.

    1. 두 개의 PublishSubject를 생성했다. subject는 이벤트 emit이 발생할 시퀀스이고, trigger는 위 그림의 Trigger역할을 해줄 시퀀스이다.

    2. subject에 takeUntil Operator가 걸렸고, 전달되는 모든 이벤트는 로그를 찍는다.

    3. subject"1", "2" 이벤트가 전달되었다. 두 이벤트는 로그가 찍혔을까?


    찍혔다.


    그럼 이제 Trigger시퀀스에 이벤트를 발생시켜보자.

    trigger.next이벤트가 발생한 뒤, subject에 "3"이벤트를 발생시켰다. "3"은 과연 로그에 찍혔을까?

    찍히지 않는다.


    takeUntil은 실전에서 아래 코드처럼 사용할 수 있다.

    viewController가 deallocated되면 더 이상 이벤트를 받지 않는다는 뜻. (사실 dispose하는게 가장 깔끔한 방법임)


    Distinct operators

    동일한 이벤트가 반복되서 발생할 수 있다. 

    예를 들어 [1, 2, 2, 2, 1, 2, 1, 1]이런 이벤트가 발생한다면 밑줄 친 부분은 동일한 이벤트가 반복된 것이다.

    distinctUntilChanged Operator를 사용하면 이렇게 동일한 이벤트가 반복되는 경우를 방어해준다. 

    위에 예시로 든 이벤트 시퀀스에 distinctUntilChanged를 적용하면 [1, 2, 1, 2, 1] 이벤트가 통과될 것이다.


    그림을 통해 살펴보자.

    2가 중복되어 발생했으니 첫 번째 2만 전달되고 두 번째 2는 무시된다.


    코드를 보자.

    1. String타입의 이벤트가 발생한다.

    2. 같은 이벤트가 연달아 발생하면 중복 이벤트는 무시하겠다.


    로그는 어떻게 찍힐까?


    예제 코드에서 사용한 StringEquatable을 따른다. 

    따라서 Equatable에 따른 Equality비교를 통해 distinctUntilChanged가 작동한 것이다.


    distinctUntilChanged(_:) Operator에 클로져를 전달하면, 커스텀한 비교 로직을 세울 수 있다.

    즉, Equatable을 따르지 않는 타입도 비교가 가능하다.

    그림을 살펴보자.

    위 시퀀스에서 발생하는 이벤트에는 value라는 값이 있다. distinctUntilChanged에 value를 비교하는 로직을 전달하고 있다.


    코드를 보자. (좀 길다)

    1. NumberFormatter를 하나 만든다. 이 친구는 숫자를 영어 스펠로 바꿔준다. Ex) 10 -> ten

    2. 10, 110, 20, 200, 210, 310 이벤트가 발생한다.

    3. distinctUntilChanged에 클로져를 하나 전달한다. 이 클로져는 어떻게 Equality를 검사하는지 보자.

    4. 전달된 이벤트 2개의 스펠을 가져온다. Ex) 10 -> ten, 110 -> onehundredten

    5. 스펠에 중복된 단어가 등장하는지 검사한다. Ex) 10, 110이 전달되면 ten이 중복해서 등장하니깐 true를 리턴함


    로그가 어떻게 찍힐까? (코드를 보고 한번 맞춰봅시다.)

    댓글 1

Designed by Tistory.