Martin Koles
Martin Koles

Reputation: 5247

How to synchronize datasource updates with tableview reloads with thread safety?

I am getting frequent updates of the tableview datasource and need to synchronize tableview updates with datasource updates properly. Can you suggest the right approach to this in Swift 3?

ListViewModel

/// Main list viewmodel refreshing and filtering API
private func refreshCards(withIcon icon: CardIcon) {

    queue.async {

        Log.debug("refresh cards Started")

        switch icon {

        case .all:

            self.loadOpenCards()
            self.loadCompletedCards()

        default:

            self.filterOpenCards(byIcon: icon)
            self.filterCompletedCards(byIcon: icon)
        }

        // Ask list TVC to reload table
        self.listTVC?.refreshForUpdates()

        Log.debug("refresh cards Finished")
    }
}

ListTableViewController

func refreshForUpdates() {

    DispatchQueue.main.async {

        self.updateApprovalListBackgroundGraphics()

        self.tableView.reloadData()

        Log.debug("refresh cards Reloaded")
    }
}

In this code tableView.reloadData() does not wait for the viewmodel refresh because it is dispatched async on the main thread.

Upvotes: 4

Views: 1604

Answers (1)

rmaddy
rmaddy

Reputation: 318824

The general approach I take in cases like this is to ensure the view controller has a static copy of the data so nothing is being changed in the background.

You have a master instance of your data model. This data model processes asynchronous updates. What it needs to do is to notify its listeners (such as a view controller) that it has been updated. The listener should respond to this update by saving off a copy of the data model and then refreshing its views (such as reloading a table view).

If the master data model happens to post another update while the view controller is updating itself, it's not a problem since the view controller won't handle that next update until it finishes updating from the previous update and the view controller's copy of the data has not yet changed with the new update.

Upvotes: 3

Related Questions