I have a table view showing search results. It has an array of all objects to search through, and an array of filtered objects, which feeds the table view.
When the user changes the text in the search bar, I update the filtered array and reload the table view. In addition, each cell has a thumbnail which is either cached or downloaded asynchronously before updating the table view cell.
So, the two places where the table view's data is reloaded are in the filtering method, which calls tableView.reloadData()
, and in the cellForRowAtIndexPath
, which calls self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimationStyle: .None)
on the main thread, if the image needed to be downloaded.
So. I've been having all kinds of problems. The three kinds of errors I've gotten:
cellForRowAtIndexPath
is trying to get the contents from the array after it's been emptied because the user changed the search text.So how can I avoid these problems? I've been trying for a couple days now to get rid of these errors but nothing I try works. Does anyone have any ideas? Thanks.
Thanks to someone on Reddit, I found the answer.
Before updating the thumbnail image after asynchronously downloading it, I needed to check if the cell is still being used for the same index path (or for any index path.) Also, I switched from asking the table view to reload the row at that index path to setting the image of the cell's image view.
Basically, inside of cellForRowAtIndexPath, after determining the image needed to be downloaded and then doing so asynchronously, I switched from this:
NSOperationQueue.mainQueue().addOperationWithBlock {
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}
to this:
NSOperationQueue.mainQueue().addOperationWithBlock {
if indexPath == tableView.indexPathForCell(cell) {
cell.imageView?.image = downloadedThumbnail
}
}
Since I made this change I haven't gotten any crashes.