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

[스터디8일차] Diffable Data Source

by 솔비님 2024. 11. 13.

 

1.  Diffable Data Source란?

TableView, CollectionView를 그리기 위한 데이터를 관리하고 UI를 업데이트 한다
기존 방식과 달리 데이터의 변경 사항을 자동으로 계산하고 애니메이션을 적용해 UI업데이트를 수행한다
핵심은 변경된 데이터만 효율적으로 업데이트 한다는 점이다

 

 

 

 

2.  DataSource Protocol과의 차이

TableView, CollectionView를 그리기 위해서는 DataSource가 필요하다

기존에는 DataSource Protocol을 채택하고, 프로토콜에 구현되어 있는 메서드를 사용하는 방법을 사용했다

 

데이터 업데이트 방식에서의 차이

기존의 DataSource Protocol는 reloadData()를 호출하여 데이터를 전체적으로 갱신한다

이렇게 하면 전체 뷰가 새로고침되어 변경되지 않은 셀도 리로드되기 때문에 불필요한 애니메이션이나 성능이 저하될 가능성이 있다

특정 행 삽입, 삭제, 업데이트 등 작업 수행 시 insertRows(at:), deleteRows(at:) 와 같은 메서드를 추가로 호출해 코드가 복잡해 지고 추가 에러 방지 코드가 필요할 수 있다

 

Diffable Data Source는 데이터의 스냅샷을 캡처하고 자동으로 데이터에서 변경된 부분을 계산해 해당 부분만 업데이트 한다

전체가 아닌 변경된 부분만 reload하기 때문에 더 자연스러운 애니메이션이 기본 적용되며,

복잡한 업데이트 메서드를 수동으로 작성할 필요가 없고 스냅샷 메서드로 데이터 변경을 처리하기 때문에 코드가 직관적이고 단순해 진다

 

 

애니메이션 처리에서의 차이

기존의 DataSource Protocol는 애니메이션을 수동으로 설정해야 하며, 직접 구현도 필요하다

잘못된 애니메이션 설정이나 충돌로 어색한 UI가 생길 수 있다

 

Diffable Data Source는 애플에서 제공하는 기본 애니메이션이 적용되어 부드러운 애니메이션이 가능하며 코드 작성이 불필요하다

apply(snapshot, animatingDifferences: true)로 간단히 애니메이션 적용 여부를 설정할 수 있다

 

 


💡 스냅샷의 역할

데이터의 현재 상태를 캡쳐하여 Diffable Data Source가 현재 데이터를 파악할 수 있게 한다

사진처럼 촬영(캡쳐)된다고 생각하는 게 이해가 빠를 것 같다

새로운 데이터가 생겨서 apply()하게될 경우 이전의 스냅샷과 새로운 스냅샷을 비교해서 변경된 부분만 계산하여 업데이트한다

이를 통해 불필요한 리로드가 없어지고 변경사항만이 효율적으로 반영된다

 

데이터 추가/변경/삭제 시 추가 메서드 호출 없이 간편하게 관리한다

: 추가(appendItems), 삭제(deleteItems), 섹션 추가(appendSections), 삭제(deleteSections


 

 

 

3.  실제 사용 예시

import UIKit

// 섹션을 구분하기 위한 열거형 정의
// 섹션타입은 데이터를 나누는 그룹으로 사용됨
enum Section: Int, CaseIterable {
    case fruits   // 첫 번째 섹션
    case vegetables // 두 번째 섹션
}

class ViewController: UIViewController {
    // 테이블 뷰와 Diffable Data Source 선언
    var tableView: UITableView!
    var dataSource: UITableViewDiffableDataSource<Section, String>!

    override func viewDidLoad() {
        super.viewDidLoad()

        // 테이블 뷰 초기화 및 설정
        tableView = UITableView(frame: view.bounds)
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") // 셀 등록
        view.addSubview(tableView)

        // Diffable Data Source 설정
        dataSource = UITableViewDiffableDataSource<Section, String>(tableView: tableView) { (tableView, indexPath, item) -> UITableViewCell? in
            // 셀을 생성하고, 각 아이템을 셀에 표시
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
            cell.textLabel?.text = item
            return cell
        }

        // 초기 데이터 설정 메서드 호출
        configureInitialSnapshot()
    }

    // 초기 데이터를 설정하는 메서드
    func configureInitialSnapshot() {
        // 스냅샷 생성
        var snapshot = NSDiffableDataSourceSnapshot<Section, String>()

        // 섹션과 아이템 추가
        snapshot.appendSections([.fruits, .vegetables]) // 열거형으로 정의한 섹션 추가
        snapshot.appendItems(["Apple", "Banana", "Orange"], toSection: .fruits) // 과일 섹션에 아이템 추가
        snapshot.appendItems(["Carrot", "Broccoli", "Pepper"], toSection: .vegetables) // 야채 섹션에 아이템 추가

        // 스냅샷을 적용하여 UI 업데이트
        dataSource.apply(snapshot, animatingDifferences: true)
    }
}

 

 

 

 

4.  RxSwift와의 유사성

RxSwift의 bind와 유사하다고 생각이 되어서 찾아본 내용

 

Diffable Data Source는 데이터 업데이트 시마다 새로운 스냅샷을 만들어서 UI에 반영한다

반응형 프로그래밍 개념보다는 스냅샷을 기반으로 데이터와 UI를 일관성있게 유지한다

데이터 변경 시에는 수동으로 apply() 메서드를 업데이트 한다(실시간/반응형 아님)

 

RxSwift는 데이터가 변할 때마다 실시간으로 UI가 자동 업데이트 된다

스냅샷을 생성하거나 수동으로 적용할 필요가 없고 데이터 흐름에 따라 자동으로 반응한다

 

 


참고자료

https://gyuios.tistory.com/153