본문 바로가기
💡 Today I Learned/스터디 자료정리

[스터디11일차][RxSwift] 테이블뷰

by 솔비님 2025. 1. 31.

RxSwift 사용 시 UITableViewDataSource와 UITableViewDelegate를 직접 구현할 필요가 없다

기존에 사용하던 방식에서는 이 두 가지를 Extention으로 분리해서 관리를 했었는데, Rx 바인딩을 통해 모두 처리할 수 있어서 코드가 간결해진다!

 


✅  RxSwift 사용 시 변경되는 것(요약)

  1. UITableViewDataSource 구현 → 없어짐 (bind(to:)로 대체)
  2. UITableViewDelegate 구현 → 없어짐 (rx.modelSelected(_:) 등으로 대체)
  3. tableView.reloadData() 호출 → 자동 업데이트
  4. DispatchQueue.main.async 필요 → Observable이 알아서 UI 스레드에서 실행
  5. indexPath.row를 직접 다루는 코드 → RxSwift가 알아서 처리

 

1.  UITableViewDataSource 구현 → 없어짐 (bind(to:)로 대체)

 

1️⃣  기존 방식

  • UITableViewDataSource 프로토콜을 구현해야 함
  • tableView(_:cellForRowAt:)에서 indexPath.row를 이용해 데이터를 설정해야 함
extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = items[indexPath.row]
        return cell
    }
}

 

 

2️⃣  RxSwift 적용

  • UITableViewDataSource 구현 없이 bind(to:)로 데이터와 UI를 바로 연결
  • 코드가 짧아지고 유지보수하기 쉬움
items
    .bind(to: tableView.rx.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { row, element, cell in
        cell.textLabel?.text = element
    }
    .disposed(by: disposeBag)

 

 


2.  UITableViewDelegate 구현 → 없어짐 (rx.modelSelected(_:) 등으로 대체)

1️⃣  기존 방식

  • 직접 UITableViewDelegate 구현하고 터치 이벤트, UI 설정, 편집 기능 등을 관리
extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("선택한 과일: \(items[indexPath.row])")
    }
}

 

 

2️⃣  RxSwift 적용

  • UITableViewDelegate 구현 없이 RxSwift 이벤트를 이용하여 선택 이벤트 처리
  • indexPath.row 없이 바로 데이터(value)를 가져올 수 있음
tableView.rx.modelSelected(String.self)
    .subscribe(onNext: { value in
        print("선택한 과일: \(value)")
    })
    .disposed(by: disposeBag)

 

 

 


3.  tableView.reloadData() 호출 → 자동 업데이트

1️⃣  기존 방식

  • 데이터가 변경될 때마다 tableView.reloadData()를 수동으로 호출해야 함
items.append("Orange")
tableView.reloadData()

 

2️⃣  RxSwift 적용

  • RxSwift는 데이터 변경을 감지하여 자동으로 UI 업데이트
  • reloadData()를 직접 호출할 필요 없음
items.onNext(["Apple", "Banana", "Cherry", "Mango", "Grapes", "Orange"])

 

 


4.  DispatchQueue.main.async 필요 → Observable이 알아서 UI 스레드에서 실행

1️⃣  기존 방식

  • 네트워크 또는 백그라운드 작업이 이뤄질 경우 UI 업데이트는 반드시 메인스레드에서 실행해줘야함
DispatchQueue.global().async {
    let newData = fetchDataFromServer() // 네트워크 호출 (예제)
    
    DispatchQueue.main.async {
        self.items = newData
        self.tableView.reloadData()
    }
}

 

2️⃣  RxSwift 적용

  • observe(on: MainScheduler.instance)를 사용하면 RxSwift가 UI 스레드에서 실행되도록 자동 처리
  • DispatchQueue.main.async를 직접 호출할 필요 없음
fetchDataFromServer()
    .observe(on: MainScheduler.instance)
    .bind(to: tableView.rx.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { row, element, cell in
        cell.textLabel?.text = element
    }
    .disposed(by: disposeBag)

 

  • UI 업데이트에 최적화된 Driver 사용 시 더 안전한 코드 작성이 가능함
  • 메인 스레드에서 실행되므로 observe(on: MainScheduler.instance) 필요 없음
  • 에러가 발생해도 앱이 크래시 나지 않고 기본값([]) 처리
fetchDataFromServer()
    .asDriver(onErrorJustReturn: []) // 에러 발생 시 빈 배열 반환
    .drive(tableView.rx.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { row, element, cell in
        cell.textLabel?.text = element
    }
    .disposed(by: disposeBag)

 

 


5.  indexPath.row를 직접 다루는 코드 → RxSwift가 알아서 처리

1️⃣  기존 방식

  • indexPath.row를 사용해서 데이터를 찾아야 함
let selectedItem = items[indexPath.row]
print("선택한 항목: \(selectedItem)")

 

2️⃣  RxSwift 적용

  • indexPath.row 없이 RxSwift가 자동으로 선택한 데이터(value)를 제공

 

tableView.rx.modelSelected(String.self)
    .subscribe(onNext: { value in
        print("선택한 항목: \(value)")
    })
    .disposed(by: disposeBag)

 

 


최종 정리

항목 기존 방식 RxSwift 적용
UITableViewDataSource 구현 numberOfRowsInSection, cellForRowAt 필수 bind(to:)로 자동 바인딩
UITableViewDelegate 구현 didSelectRowAt에서 직접 처리 rx.modelSelected(_:)로 간단히 처리
tableView.reloadData() 데이터 변경 시 reloadData() 호출 필요 RxSwift가 자동으로 UI 업데이트
DispatchQueue.main.async 필요 백그라운드에서 UI 업데이트 시 필수 Rx가 UI 스레드에서 자동 실행
indexPath.row 직접 다루기 indexPath.row를 사용해서 데이터 접근 Rx가 자동으로 데이터 제공