학습 이유
컬렉션 뷰/테이블 뷰를 데이터 기반으로 동작하고자 했었음
- 예. item 변수에 프로퍼티 옵저버를 통해 데이터가 바뀌면 자동으로 reloadData() 수행
하지만, 프로퍼티 옵저버를 통해 뷰를 관리하니 애니메이션이 존재하는 상황에서 크래시가 발생
이유는 제스쳐를 통해 셀 삭제 등을 수행할 때
- 사용자가 셀 삭제()
- 인덱스패스를 기반으로 데이터 remove
- 데이터가 변경되니 reloadData() 트리거
- 데이터에는 존재하지 않는데, 뷰에는 데이터가 존재하는 상태에서 인덱스 오류가 발생
- 앱 크래시
이러한 이유에서 인덱스 기반의 DataSource가 아닌 식별자 기반의 DiffableDataSource를 학습하기로 함
DataSource
데이터를 관리하고, CollectionView/TableView에 셀을 제공하기 위해 채택하는 방법
-> 컬렉션 뷰와 테이블 뷰에 셀을 제공하기 위한 방법
DataSource는 데이터를 관리
- 앱의 데이터 모델
- 필요에 따라 정보를 제공
- 데이터를 표시하는 데 사용하는 셀과 하위 뷰를 생성/구성
- Delegate 방식
- collectionView(:numberOfItemsInSection:), collectionView(:cellForItemAt:), ...
- IndexPath 기반
DiffableDataSource
사용 방법
- 디퍼블 데이터 소스를 컬렉션 뷰/테이블 뷰에 연결
- cellProvider 구현하여 셀 구성
- 데이터 현재 상태 생성
- UI에 데이터 표시
DiffableDataSource를 사용하는 이유
컬렉션 뷰는 Section과 Item 형태로 데이터를 표시
레시피를 표시하는 앱을 예로 들면, 앱을 사용하는 사람은 레시피를 추가, 삭제, 즐겨찾기 등으로 표시할 수 있다.
이러한 작업을 위해 컬렉션 뷰 내에서 데이터 삽입, 삭제, 이동, 업데이트를 지원
UICollectionViewDataSource 프로토콜을 채택하는 DataSource를 만들어 사용 시, 컬렉션 뷰를 최신 상태로 유지하려면 변경된 데이터를 결정하고, 이러한 변경 사항을 기반으로 일괄 업데이트(performBatchUpdates)를 수행
이러한 프로세스의 복잡성을 피하기 위해 DiffableDataSource를 사용한다.
DataSource vs. DiffableDataSource
DataSource는 인덱스와 인덱스패스를 사용해 데이터를 관리한다.
- 이는 데이터가 변경됨에 따라 인덱스가 변경되기 때문에 안정적이지 않을 수 있다.
DiffableDataSource는 식별자를 기준으로 데이터를 관리
- 위치에 대한 정보를 알지 않아도 섹션이나 아이템을 참조할 수 있음
DiffableDataSource+Hashable
DiffableDataSource를 사용하기 위해 Hashable을 채택한 데이터 타입을 사용
- 해싱을 통해 빠르고, 효율적인 조회 제공
식별자는 Hashable, Equatable하기 때문에 현재 스냅샷과 다른 스냅샷의 차이점을 결정할 수 있음
이러한 점을 통해 일괄 업데이트가 필요하지 않으며, 빠르게 동작함
후기
디퍼블 데이터 소스를 사용하는 게 모든 상황에서 이상적이진 않은 것 같다
- 디퍼블 데이터 소스는 빈번하게 변화하는 데이터를 기반으로 한 뷰에서 쓰기 적합하다고 생각
선택한 셀의 id를 통해 api를 요청하거나, 좋아요 기능 등을 구현하기에는 적합한 것 같으나, 한 번 데이터를 불러오고 변화가 없는 상황에서는 기존 데이터 소스를 통해 구현하는 게 좋을 것 같다.
참고
https://developer.apple.com/documentation/uikit/uicollectionviewdatasource
https://developer.apple.com/documentation/uikit/uitableviewdatasource
https://developer.apple.com/documentation/uikit/updating-collection-views-using-diffable-data-sources
https://developer.apple.com/kr/videos/play/wwdc2019/220
'Swift > UIKit' 카테고리의 다른 글
| UIKit: 원형 컨텍스트 메뉴 라이브러리 (0) | 2025.10.21 |
|---|---|
| RxSwift와 Diffable DataSource에서의 ModelSelected 구현 (0) | 2025.09.10 |
| UIKit: UITextView (1) | 2025.08.30 |
| UIControl 이벤트를 Combine 퍼블리셔로 만들기 (0) | 2025.08.20 |
| 버튼을 통해 IndexPath 전달하기 (2) | 2025.08.18 |