Diffable Data Source cached cells issue

Hi, developers!

I use DiffableDataSource for myTableView and was surprised when I found that TableView in this case caches previously created cells after (or before) a new update. It seems that this is implemented to store cell states and quickly update if the contents of the table change.

Because of this mechanism, I have the following problem: my cells use reference-type view models, which in turn contain notification observers from the file upload service. The view model is connected to the cell with a closure, which is called upon notification and updates, for example, the progress scale in the cell

After uploading the file, I make a new applySnapshot using similar models with cameras (but, for example, the "fileName" field is already different, so I need to change it in cell).

Due to caching of cells in memory, the old view models with observers are not released, as a result, I get two observers, for two different cells, one of which is visible, and the second is not. This causes problems with UI. To summarize, my question is, is it possible to disable cell caching or clean the cache if using Diffable Data Source manually?

Accepted Reply

It's difficult to say for sure what the best solution is from your description alone. But have you investigated using the UITableView lifecycle callbacks when cells display & end displaying for a row? Specifically, you could use the didEndDisplaying callback to know when a cell stops displaying for a given row, and disconnect the observer in that case. Just know that you'd also want to ensure the connection is re-established in the corresponding willDisplay callback, as if the cell is scrolled slightly out of view and then back in, it will remain in the UITableView's internal cache of prepared cells which get displayed again without going through the cellForRowAt callback (i.e. your diffable cell provider).

If necessary, you can disable cell prefetching using this property, however this is not recommended as it will negatively impact scrolling performance (causing user-visible hitches and increased power usage during scrolling).

Replies

It's difficult to say for sure what the best solution is from your description alone. But have you investigated using the UITableView lifecycle callbacks when cells display & end displaying for a row? Specifically, you could use the didEndDisplaying callback to know when a cell stops displaying for a given row, and disconnect the observer in that case. Just know that you'd also want to ensure the connection is re-established in the corresponding willDisplay callback, as if the cell is scrolled slightly out of view and then back in, it will remain in the UITableView's internal cache of prepared cells which get displayed again without going through the cellForRowAt callback (i.e. your diffable cell provider).

If necessary, you can disable cell prefetching using this property, however this is not recommended as it will negatively impact scrolling performance (causing user-visible hitches and increased power usage during scrolling).