I'm trying to wrap my head around the new DiffableDataSource
way of handling data in tableviews/collectionviews and during testing I came across a strange crash.
I would expect that the two implementations below would work exactly the same:
Implementation 1:
class DiffableSection {
var id: String
var items: [AnyDiffable]
init(id: String,
items: [AnyDiffable] = []) {
self.id = id
self.items = items
}
}
extension DiffableSection: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
extension DiffableSection: Equatable {
static func == (lhs: DiffableSection, rhs: DiffableSection) -> Bool {
return lhs.id == rhs.id
}
}
Implementation 2:
class DiffableSection: NSObject {
var id: String
var items: [AnyDiffable]
init(id: String,
items: [AnyDiffable] = []) {
self.id = id
self.items = items
}
// MARK: - Hashable and Equatable
public override var hash: Int {
var hasher = Hasher()
hasher.combine(id)
return hasher.finalize()
}
public override func isEqual(_ object: Any?) -> Bool {
guard let object = object as? DiffableSection else { return false }
return id == object.id
}
}
but apparently they are not - Implementation 2
works with the code below and Implementation 1
does not.
func apply(_ sections: [DiffableSection]) {
var snapshot = self.snapshot()
for section in sections {
snapshot.appendSectionIfNeeded(section)
snapshot.appendItems(section.items, toSection: section)
}
apply(snapshot)
}
(...)
extension NSDiffableDataSourceSnapshot {
mutating func appendSectionIfNeeded(_ identifier: SectionIdentifierType) {
if sectionIdentifiers.contains(identifier) { return }
appendSections([identifier])
}
}
The crash message I get when running with Implementation 1
:
'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: section != NSNotFound'
Can someone explain me what are the differences in those implementations? How could I fix Implementation 1
to work same as Implementation 2
??