RxSwift

RxSwift | distinctUntilChanged

ziziDev 2024. 12. 11. 12:01
반응형

distinctUntilChanged

는 연속으로 중복된 값을 방출하지 않습니다.

🔍 distinctUntilChanged란?

distinctUntilChanged는 RxSwift의 연산자로, 이전 값과 새 값이 동일한 경우 방출을 방지하는 기능을 제공합니다.

  • 연속으로 중복된 데이터(값)를 한 번만 방출합니다.
  • 이전에 방출된 값과 현재 값이 같으면 데이터 스트림에 방출되지 않습니다.
  • 값이 변경될 때만 새로운 값이 스트림으로 전달됩니다.

💡 왜 사용해야 할까?

  • 불필요한 UI 업데이트 방지: 뷰를 다시 그리는 것을 막음.
  • 불필요한 연산을 방지: 동일한 데이터를 다시 계산하거나 네트워크 요청을 하지 않음.
  • 성능 향상: UI가 중복 업데이트되지 않아 성능이 향상됨.
  • 불필요한 구독 제거: 데이터가 바뀌지 않았을 때는 방출하지 않으므로 구독자에게 불필요한 알림을 보내지 않음.

🧑‍💻 어떻게 동작할까?

1️⃣ 기본 동작

  • 이전 값과 현재 값이 다를 때만 방출합니다.
  • 예를 들어, 1, 1, 2, 2, 3, 3, 3이 있으면, 중복 값은 제거하고 1, 2, 3만 방출합니다.

📘 코드 예시

import RxSwift

let disposeBag = DisposeBag()

Observable.of(1, 1, 2, 2, 3, 3, 3, 4, 4, 4)
    .distinctUntilChanged()
    .subscribe(onNext: { value in
        print("방출된 값: \(value)")
    })
    .disposed(by: disposeBag)
//방출된 값: 1
//방출된 값: 2
//방출된 값: 3
//방출된 값: 4

 

let disposeBag = DisposeBag()

struct User {
    let id: Int
    let name: String
}

let users = Observable.of(
    User(id: 1, name: "Alice"),
    User(id: 1, name: "Alice"),
    User(id: 2, name: "Bob"),
    User(id: 2, name: "Charlie") // 이름은 다르지만 id가 동일함
)

users
    .distinctUntilChanged { $0.id == $1.id } // id로만 비교
    .subscribe(onNext: { user in
        print("사용자 방출: \(user.name)")
    })
    .disposed(by: disposeBag)
    
//사용자 방출: Alice
//사용자 방출: Bob

🛠️ 정리

문제 상황해결 방법 (distinctUntilChanged)

중복된 사용자 입력 방지 중복된 텍스트를 방출하지 않음
불필요한 API 호출 방지 같은 요청을 한 번만 API로 보냄
중복된 UI 업데이트 방지 스피너, 버튼 상태 변경 등 중복 방지
중복 데이터 방출 방지 중복된 값을 구독자에게 방출하지 않음

🚀 결론

  • distinctUntilChanged는 연속으로 중복된 값을 방출하지 않습니다.
  • 중복된 사용자 입력, 중복된 UI 업데이트, 불필요한 API 요청을 방지할 수 있습니다.
  • 기본 비교는 값 자체를 비교하지만, 필요에 따라 커스텀 비교 함수도 추가할 수 있습니다.
  • 성능 최적화와 불필요한 연산을 줄이는 필수적인 연산자입니다.
반응형

'RxSwift' 카테고리의 다른 글

RxSwift | RxSwfit 배우는 이유 + 사용하는 이유  (0) 2024.12.04