Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 11 UITableView performBatchUpdates completion closure not being called

I have a UITableView which is displaying an aggregated feed of posts from several RSS feeds. Whenever my app pulls new posts from a feed, I create an object representing all of the needed insertions and deletions needed to update the UITableView current rows. I place these objects into an array which I use as a FIFO queue. Every few seconds, I pull the first element out of this array and attempt to perform all of the insertions and deletions within the UITableView using the function UITableView:performBatchUpdates.

This all works great ... so long as the user doesn't scroll the UITableView up and down. If there is scrolling going on, the updates will cease, because I am setting a flag to ensure that I always wait until the last set of insertions/deletions has completed before I start the next batch, and sadly, sometimes, the completion closure of UITableView:performBatchUpdates never gets called, hence my flag is never cleared.

Here is the code I'm using to process my incoming queue of changes for the UITableView:

@objc func updateFeedPostsTableView() {

    guard feedUpdateQueue.count > 0,
          !feedTableUpdateInProgress else { return }

    feedTableUpdateInProgress = true
    let feedUpdate = feedUpdateQueue.first!
    feedUpdateQueue.remove(at: 0)

    self.aggregatedRSSFeed = feedUpdate.feed

    self.feedPostsTableView.performBatchUpdates ({
        self.feedPostsTableView.deleteRows(at: feedUpdate.indexPathsOfDeletedPosts,
                                           with: .fade)
        self.feedPostsTableView.insertRows(at: feedUpdate.indexPathsOfNewPosts,
                                           with: .top)
        },
        completion: { (success) in
            self.feedTableUpdateInProgress = false
        }
    )
}

My question is, why would UITableView.performBatchUpdates ever fail to call its completion block? What am I doing wrong here?

This is iOS 11.2, using Xcode version 9.2.

Thanks!

like image 622
Greg Anderson Avatar asked May 22 '18 03:05

Greg Anderson


People also ask

What is performBatchUpdates?

updates. The block that performs the relevant insert, delete, reload, or move operations.

When performing batch updates on a Uitableview the indexes for the deletions are processed relative to?

This means the indexes for the deletions are processed relative to the indexes of the collection view's state before the batch operation, and the indexes for the insertions are processed relative to the indexes of the state after all the deletions in the batch operation.


1 Answers

I was having this problem. The main performBatchUpdates block was getting executed but the completion block was never called. I found out that the issue was caused by me using a subclass of UITableView. As soon as I switched back to a vanilla UITableView the problem went away.

Lesson learned. Don't subclass UITableView.

like image 142
iamiend Avatar answered Sep 30 '22 18:09

iamiend