Josip B.
Josip B.

Reputation: 2464

UICollectionViewDiffableDataSource - Crash when having equal items with different hash

I am using UICollectionViewDiffableDataSource to fill UICollectionView with data. My understanding is that DiffableDataSource compares items by using == and then if items are equal it compares hash values to see if something changed.

But according to the error I am getting this isn't the case.

Diffable data source detected item identifiers that are equal but have different hash values. Two identifiers which compare as equal must return the same hash value. You must fix this in the Hashable (Swift) or hash property (Objective-C) implementation for the type of these identifiers

In my case I have item that I compare against uniqueID and hashValue is determined by value that user entered. What is the point of using == and hashValue if they can't be different?

Upvotes: 7

Views: 945

Answers (1)

hstdt
hstdt

Reputation: 6243

workaround: equaltable by hashValue and uniqueID to avoid equal but have different hash values crash.

static func == (lhs: Item, rhs: Item) -> Bool {
   lhs.hashValue == rhs.hashValue && lhs.id == rhs.id
}

Maybe not a perfect solution. In my case, I only need == for moving animation, so I send changed value by notification when only one item changes and needs moving, and replacing item after animation:

dataSource.apply(snapshot, animatingDifferences: true) { [weak self] in
    guard let self else { return }
    snapshot.insertItems([newItem], beforeItem: item)
    snapshot.deleteItems([item])
    snapshot.reconfigureItems([newItem])
    dataSource.apply(snapshot, animatingDifferences: false)
}

Couldn't agree more with 'What is the point of using == and hashValue if they can't be different' :)

Upvotes: 0

Related Questions