Reloading data causes crash when scrollToRow is called after it. I have to write this code in DispatchQueue.main.async
but, why?
Why should I say to switch to the main queue when I have been in the main queue?
self.tableView.reloadData()
print(Thread.current). // It is main
self.tableView.scrollToRow(at: indexPathToScroll, at: .top, animated: false)
print(Thread.current). // It is main
The error is:
_contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:usingPresentationValues:]: row (20) beyond bounds (20) for section (0).
The problem was solved in this way:
DispatchQueue.main.async(execute: {
self.tableView.reloadData()
print(Thread.current). // It is main
self.tableView.scrollToRow(at: indexPathToScroll, at: .top, animated: false)
print(Thread.current). // It is main
})
As I printed in the first code it was run in the main thread. Why DispatchQueue.main.async
made difference?
Simplest answer I found is from GCD Main queue vs Main thread
While every app will ever only have one main thread, it is possible for many different queues to execute on this one main thread.
Certain APIs rely not only on running on the main thread, but also on the main queue, it is safer to check for the current queue instead of checking for the current thread.