12

Using UITableView with a custom cell. This was working fine till using iOS SDK 14. When start using iOS sdk 15, UITableView gives error upon scrolling.

Error is "Assert UITableView internal inconsistency prefetchedCells and indexPathsForPrefetchedCells are out of sync"

Because of this error cells starts disappear randomly.

kapill
  • 189
  • 9

3 Answers3

13

This assert indicates that the UITableView internal state is "corrupted". The most frequent cause is when the table view is performing an update or reload, and is in the middle of a callback to one of the data source or delegate methods, and somehow your code causes unexpected "reentrancy" on the UITableView (e.g. by performing another update/reload or by manually running the main runloop) from inside this callback. This causes UITableView to get into an inconsistent internal state because it's already in the middle of processing another update.

In my case I have a bad interaction between UITableView and the NSAttributedString() init method that using SwiftSoup to converts html to an attributedString. It was being called while updating a tableViewCell and this caused cellForRowAt to be called again while my app code was already processing a cellForRowAt call. And the tableView lost its mind after that.

I fixed this problem by converting html to an attributedString earlier before cellForRowAt run, then cellForRowAt using it.

user1578860
  • 131
  • 1
  • 3
  • 1
    i solved by moving attributed string with html content from cellfroRowAtIndex. and i have prepared the attributed string during model creation. – ram880 Sep 12 '22 at 10:07
  • Another alternative is to put the NSAttributedString processing into a background task from within `cellForRowAt`. Since the results for this task are fairly expensive to create, you can also cache them with a technique like you'd use for images. – chockenberry Mar 31 '23 at 17:32
  • This fixed a similar issue for me. But why is this happening? In my case its a simple conversion of HTML to NSAttributedString using `let attrStr = try! NSAttributedString( data: modifiedFont.data(using: .utf8, allowLossyConversion: false)!, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil)` Why does this conversion to NSAttributedString cause UITableView to go crazy, or "lose its mind"? I would like to understand the reason. – David Apr 24 '23 at 03:37
2

I also faced this problem. After a long search, I found this video:

Apple WWDC2021

Some performance improvements made by Apple broke the nested UITableView I used.

I changed the value of UITableView's isPrefetchingEnabled to false. You can apply it to a specific TableView, or you can change it for whole app.

if #available(iOS 15.0, *) {
    UITableView.appearance().isPrefetchingEnabled = false
}
ZGski
  • 2,398
  • 1
  • 21
  • 34
  • I wouldn't like to disable prefetching feature because of this issue. I'm sure something else is happening. Did you use NSAttributedString in your cells? – caperonce Nov 18 '22 at 13:07
  • No, I did not. My first cell layer contains UILabel and UITableView. The second one has UILabels and UIImageView. – Bahadirovski Nov 19 '22 at 14:41
0

This can happen when the exact same instance of a cell is rendered to two different rows in the same table. In the case I saw, the same cell instance was added as the first row to two different sections.

1192805
  • 988
  • 2
  • 10
  • 26