티스토리 뷰
# 문제
저번글의 예제앱에서 사용한 데이터를 보겠습니다.
var arr = ["Zedd","Alan Walker", "David Guetta", "Avicii", "Marshmello", "Steve Aoki", "R3HAB", "Armin van Buuren", "Skrillex", "Illenium", "The Chainsmokers", "Don Diablo", "Afrojack", "Tiesto", "KSHMR", "DJ Snake", "Kygo", "Galantis", "Major Lazer", "Vicetone"
]
여기에는 큰 문제가 있습니다.
var arr = ["Zedd", ✅"Zedd"✅,"Alan Walker", "David Guetta", "Avicii", "Marshmello", "Steve Aoki", "R3HAB", "Armin van Buuren", "Skrillex", "Illenium", "The Chainsmokers", "Don Diablo", "Afrojack", "Tiesto", "KSHMR", "DJ Snake", "Kygo", "Galantis", "Major Lazer", "Vicetone"
]
이렇게 “Zedd”를 한번 더 넣게 되면
DiffableDataSource_Example[75856:2941803] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Fatal: supplied item identifiers are not unique.'
이런 에러를 내며 crash가 나게 됩니다.
# 원인
저번 글에서 SectionIdentifierType과 ItemIdentifierType은 Hashable을 준수해야한다고 했습니다.
String은 Hashable을 준수하고 있으므로 ItemIdentifierType으로 들어갈 수 있었죠.
var arr = ["Zedd", ✅"Zedd"✅,"Alan Walker", "David Guetta", "Avicii", "Marshmello", "Steve Aoki", "R3HAB", "Armin van Buuren", "Skrillex", "Illenium", "The Chainsmokers", "Don Diablo", "Afrojack", "Tiesto", "KSHMR", "DJ Snake", "Kygo", "Galantis", "Major Lazer", "Vicetone"
]
"Zedd"에 대한 Hash값이 1이라면, 그 다음 "Zedd"에 대한 Hash값도 1입니다.
Diffable datasource는 ItemIdentifier에 대해서 고유한 Hash값을 요구하는데요.
Hash값이 같은것이 있음 ==> identifier가 고유하지 않음 ==> crash
이런 문제가 있는것입니다.
# 개선
supplied item identifiers are not unique.
이게 원인이니 유니크하게 만들어주면됩니다. 즉 다른 Hash값을 가질 수 있도록 해주면 됩니다.
그럼
var arr = ["Zedd","Alan Walker", "David Guetta", "Avicii", "Marshmello", "Steve Aoki", "R3HAB", "Armin van Buuren", "Skrillex", "Illenium", "The Chainsmokers", "Don Diablo", "Afrojack", "Tiesto", "KSHMR", "DJ Snake", "Kygo", "Galantis", "Major Lazer", "Vicetone"
]
이 친구들이 String으로 되어있는 이상 hashValue uniqueness문제는 항상 발생할 수 있습니다.
그러므로 같은 이름을 가지고 있지만 다른 Hash값이 나올 수 있도록 해보겠습니다.
1. 타입 정의
[String]으로는 할 수 있는게 없으므로..Custom Type을 만들어주겠습니다.
struct DJ: Hashable {
var name: String
}
DJ를 만들고 Hashable을 준수해야하므로 Hashable을 준수하도록 해줍니다.
struct DJ: Hashable {
var name: String
}
let zedd1 = DJ(name: "Zedd")
let zedd2 = DJ(name: "Zedd")
자 이렇게 하면, zedd1과 zedd2의 hashValue는 다를까요?
아닙니다. 같습니다.
print(zedd1.hashValue == zedd2.hashValue) // true
DJ타입의 경우 hashValue를 생성하기 위한 프로퍼티가 name하나밖에 없는데, 이게 같으니 hashValue도 같을 수 밖에 없는 것이죠.
name은 같지만, hashValue를 다르게 할 다른 프로퍼티가 필요합니다.
struct DJ: Hashable {
var address: String
var name: String
}
let zedd1 = DJ(address: "Earth", name: "Zedd")
let zedd2 = DJ(address: "Mars", name: "Zedd")
print(zedd1.hashValue == zedd2.hashValue) // false
이런식인거죠.
하지만 address이런 필요없는(?) 프로퍼티 정의보다 나은 방법이 있습니다.
바로 UUID를 사용하는 것이죠.
2. id 프로퍼티 정의
UUID는 타입, 인터페이스 및 기타 항목을 식별하는 데 사용할 수 있는 보편적으로 고유 한 값입니다.
그래서
struct DJ: Hashable {
let id = UUID()
var name: String
}
이렇게 id값을 정의해줬습니다.
struct DJ: Hashable {
let id = UUID()
var name: String
}
let zedd1 = DJ(name: "Zedd")
let zedd2 = DJ(name: "Zedd")
print(zedd1.hashValue == zedd2.hashValue) // false
이렇게 간단하게 hashValue를 다르게 할 수 있습니다.
3. ItemIdentifierType바꿔주기
var dataSource: UICollectionViewDiffableDataSource<Section, String>!
저번 글에서 ItemIdentifierType이 이렇게 String으로 들어가있을텐데, 이런것들을 전부 DJ타입으로 바꿔주면 됩니다.
자세한 변경사항은 github을 참고해주세요.
이렇게하면..
Crash안나고 잘 되는 것을 볼 수 있습니다.
ㅎㅎ..이걸 저번글에서는 몰랐어가지고...많이 중요한건데 ㅎ ㅏㅎ ㅏ..
'공부' 카테고리의 다른 글
Carthage (0) | 2021.04.15 |
---|---|
Swift ) Quick / Nimble 간단하게 사용해보기 (0) | 2021.04.14 |
Diffable Datasource (3) | 2021.04.06 |
TextStyle과 UIFontMetrics(with Custom Font) (0) | 2021.04.05 |
HIG ) Color and Contrast (0) | 2021.04.01 |
- 제이슨 파싱
- IOS
- Combine
- github
- UIBezierPath
- Swift
- WKWebView
- swift tutorial
- fastlane
- np-hard
- Git
- Accessibility
- np-complete
- swift 공부
- 스위프트 문법
- WidgetKit
- swift delegate
- swift array
- swift sort
- swift3
- 피아노
- SwiftUI
- Xcode
- actor
- 스위프트
- 회고
- WWDC
- ios 13
- FLUTTER
- iOS delegate
- Total
- Today
- Yesterday