0

I have a swift project, with a UITableView that's populated by a UITableViewDiffableDataSource.

In my model struct, I've implemented the hash() function, roughly like this:

func hash(into hasher: inout Hasher) {
            hasher.combine(self.id)
            hasher.combine(self.mandatory)
            hasher.combine(self.isHidden)
            hasher.combine(self.readOnly)
            hasher.combine(self.type)

            // These 2 lines are obviously not part of the code, they're for debugging.
            let value = hasher.finalize()
            print("******************* hash value is \(value)")
}

When one of the values in the table changes, I call UITableViewDiffableDataSource.apply.

Worth noting at this point: the model class has a currentValue that holds the actual value, that is by design not factored into the hash function.

On an iOS 15.5 simulator, it works as expected - when the value of a cell changes, the cell is not re-rendered, and the hash values logged to the console are identical.

When running the same code on an iOS 14.3 simulator though, the logs still show identical hash values, and the == overriden function isn't called, yet the cell is re-rendered.

What am I missing here? Why is iOS 14 re-rendering the cell despite the hash values being identical?

Also, just to avoid being sidetracked - I simplified the issue for the sake of brevity, so please ignore the fact that I ignore the value in the hash function, it's by design and very deliberate, despite it at first sounding like bad practice.

Avi Sasson
  • 666
  • 7
  • 22
  • "Why is iOS 14 re-rendering the cell despite the hash values being identical?" It's a bug that was fixed in iOS 15? – matt Sep 13 '22 at 11:43
  • @matt Do you know it is? Or are you just guessing? I obviously looked it up before asking, couldn't find any documentation of such bug – Avi Sasson Sep 13 '22 at 11:44
  • Really? Where did you "look it up"? This was a very common complaint on Stack Overflow starting in iOS 13. I can find lots of examples along with mention of the big iOS 15 improvements. – matt Sep 13 '22 at 12:02
  • Could you please link any of them? I tried various searches, such as "swift, UITableViewDiffableDataSource, re-render despite same hash" and "swift, UITableViewDiffableDataSource, not calling ==". Maybe one of those threads has a workaround? – Avi Sasson Sep 13 '22 at 12:03
  • The usual workaround is not to animate differences and/or use a struct instead of a class as your model. – matt Sep 13 '22 at 12:05
  • My model is already a struct, so that's probably not the issue. What do you mean by "not animate differences"? Is it a parameter I'm supposed to pass to UITableViewDiffableDataSource.apply? – Avi Sasson Sep 13 '22 at 12:06
  • Oh wait, nevermind, I see it. I'm already passing animatingDifferences: false to .apply()... – Avi Sasson Sep 13 '22 at 12:07
  • Yes it is. — You did say it was a class, you know. – matt Sep 13 '22 at 12:07
  • It was a mistake on my part then, it's declares as such: struct Input: Codable, Hashable. – Avi Sasson Sep 13 '22 at 12:08
  • Whatever. I've given you some good clues based on the incredibly limited (and false) info you provided. – matt Sep 13 '22 at 12:09
  • I appreciate your help. Could you link me one of those threads you found on the matter? You mentioned it was "a very common complaint on Stack Overflow". – Avi Sasson Sep 13 '22 at 14:04

0 Answers0