먼저 공식문서가 설명하는 diffabledatasource 사용의 이유를 알아보자
Updating Collection Views Using Diffable Data Sources
Diffabledatasource can streamline the display and update of data in a collection view using a diffable data source that contains identifiers.
➡️ dffiable datasources는 자신이 가지고 있는 identifiers를 통하여 collection view의 data를 업데이트하고 매끄럽게 보여줄 수 있다.
A diffable data source stores a list of section and item identifiers, which represents the identity of each section and item contained in a collection view.
➡️ Diffabledatasource는 Collectionview에 포함된 각 섹션 및 항목의 아이덴티티를 나타내는 섹션 및 항목 identifier 목록을 저장합니다.
These identifiers are stable, meaning they don’t change.
➡️ 이러한 identifiers는 안정적입니다. 즉, 변하지 않습니다!
In contrast, a custom data source that conforms to UICollectionViewDataSource uses indices and index paths, which aren’t stable. They represent the location of sections and items, which can change as the data source adds, removes, and rearranges the contents of a collection view.
➡️ 반대로, UICollectionViewDataSource
를 채택한 datasource의 경우, index path를 활용하여 안정적이지 않습니다. 이는 section과 item의 위치를 가르키는데, datasource가 collection view의 content를 추가되고, 제거되고, 재배열될 때 같이 변경될 수 있습니다.
However, with identifiers a diffable data source can refer to a section or item without knowledge of its location within a collection view.
➡️ 그러나, identifer를 사용할 경우, collection view의 위치 개념을 가지고 있는 indexpath를 사용하지 않고, section과 item을 가르킬 수 있습니다.
즉, diffabledatasource를 사용하는 이유는 크게 두 가지이다!
- collection view의 위치 개념을 통하여 section, item을 가르키는 indexpath를 사용하지 않고, 절대 변하지 않는 identifiers들의 배열을 통해서 datasource를 구성하기에 데이터가 추가, 삭제, 재배열될 때, 훨씬 안정적이다.
- 데이터가 변경될 때, 매끄러운 애니메이션을 활용해서 업데이트할 수 있다.
그렇다면, 본격적으로 왜 diffabledatasource의 identifier는 hashable 해야하는 지 알아보자.
먼저 Hash 값이란?
- 데이터를 간단한 숫자로 변환한 것!
- 원본 데이터를 특정 규칙에 따라 처리하여 간단한 숫자(Int)로 만든 것!
- 두 가지의 서로 다른 데이터가 동일한 해쉬 값을 가질 수 있다.
- 해쉬 충돌이 발생할 수 있다. ⇒ 연결 리스트, 선형 조사법 등으로 해결할 수 있다.
- Dictionary에서 key를 해시 함수를 통해서 해시 주소 값(해시 테이블의 Index)으로 바꾸고, 해당 해시 주소 값을 통해서 해시 테이블에 접근하여 Value를 해시 테이블에 저장한다.
- 이러한 방식은 기존의 검색 속도보다 더 빠르다!
- 따라서, Swift의 Dictionary의 key 값은 무조건
Hashable
해야된다.- Hashable하면 훨씬 빠르게 이 값이 다른 지, 같은 지를 탐색할 수 있다!
Hashable
A type that can be hashed into a Hasher
to produce an integer hash value.
Hashable
한 타입의 데이터는 해쉬 값을 구할 수 있다.
protocol Hashable : Equatable
- String, Integer, floating, Boolean value, Set은 이미 default로 hashable을 채택하고 있다.
- 만약 Optional이랑, 배열 및 range가 hashable한 인자로 되어있다면, 해당 타입도 hashable하다.
- 연관 값이 없는 enum 타입은 자동적으로 Hashable을 만족한다.
- Custom type에서도
hash(into:)
메소드를 통해서 Hashable하게 만들 수 있다. - 모든 저장 프로퍼티가 Hashable한 구조체나, 연관 값이 다 Hashable한 enum 타입은 컴파일러가 자동적으로
hash(into:)
메소드를 실행시킨다.
// combine 함수는 들어온 value를 hash 값으로 바꿔준다.
func hash(into hasher: inout Hasher) {
hasher.combine(identifer)
}
왜? Equatable을 준수 해야될 까?
- 해시 충돌 시(두 가지의 서로 다른 데이터가 동일한 해쉬 값을 가질 수 있다.), 같은 index에 Key-Value 값을 연결 리스트 형식으로 저장하기에 Value 값에 접근할 때에 연결 리스트 노드 중에서 key를 비교하여(=) 알맞은 Value를 꺼내기 위해서!
왜 Hashable을 채택해야 될까?
- 일단,
DiffableDataSource
가 나오게 된 이유를 알아야 된다.- 값이 제거되는 식의 동작이 일어날 때 index의 sync가 제대로 맞지 않아서 크래시가 발생하는 경우들이 빈번하여 reloadData(), performBatchUpdates()등을 통해서 통째로 데이터를 업데이트를 했다.(UI 업데이트 측면에서 사용자 경험 ⬇️)
- 근데, DiffableDataSource를 통해서 변경된 데이터만 확인해서 해당 데이터만 변경하려고
DiffableDataSource
가 나오게 되었다.(맨 위의 글과 비슷한 내용이죠!)
- 어떤 데이터가 변경되었는 지 확인을 위해서는 업데이트되는 데이터 셋 속의 item들은 유일해야 된다!
- 예) [”Miro”, “Miro”, “Yagom”] ⇒ [”Miro”, “Finn”, “Yagom”] 에서 무슨 “Miro”가 변경되었는 지 알아야되는데, 유일하지 않은 item이 존재하면 뭐가 변경되었는 지 알 수가 없다.
Hashable
을 채택하면!거의 매번 다른 해쉬 값을 통해서 서로 다른 identifier를 생성할 수 있다. ⇒ 즉, 고유한 identifier를 만드는 것을 자연스럽게 보장할 수 있다!- Hashable을 채택해도 같은 해쉬 값을 가진 identifier를 만들 수 있다!!
- 그리고 Equatable을 채택을 해서 서로 다른 지 확인(==)할 수 있는데, 두 개의 스냅 샷을 서로 비교하는 과정에서 해쉬 값으로 비교를 하므로 훨씬 더 빠르게 서로 다른 지를 확인할 수 있다.
- 즉, 공식문서에서는 providing quick and efficient lookups. → 빠르고 효율적으로 탐색할 수 있다고 나와있다!
📚 참고 자료
Updating Collection Views Using Diffable Data Sources | Apple Developer Documentation
'iOS' 카테고리의 다른 글
[iOS] 공식문서로 보는 Core Location (0) | 2023.07.16 |
---|---|
[iOS] delegate는 항상 weak var로 선언해야 될까? (0) | 2023.06.12 |
[iOS] FileManager (0) | 2023.06.08 |
[iOS] NotificationCenter (0) | 2023.04.13 |
[iOS] Gesture recognizer, Touch event handling (0) | 2023.02.28 |