Asynchronous refresh of uitableview reloaddata

Time:2022-4-21

Introduction:

Reloaddata of uitableview is asynchronous. After calling this method, it will continue to execute other codes (such as tableview layout, cell display, height calculation and other proxy methods, or some of its own codes), and will not block the main thread; That is, reloaddate does not wait for the tableview to be updated before returning, but returns immediately. In this way, it will be impossible to determine the completion time after reloaddata, and it will be impossible to do other operations in time after reloaddata is completed (for example, scroll to the specified cell); If the data in the table is large or the layout is complex, and the execution of a run loop cycle is not completed, there will be problems when the operation of the tableview view data is required (for example, scrolling to the specified cell).
The problem code is as follows:

        self.tableView?.reloadData()
        self.tableView?.scrollToRow(at: IndexPath.init(row: self.selectedIndex, section: 0), at: .none, animated: true)

How to solve this problem, that is, how to obtain the completion time of reloaddata? There are three methods. The implementation and principle of these three methods are as follows:

Method 1: call layoutIfNeeded after reloadData base note.

realization:

        self.tableView?.reloadData()
        self.tableView?.layoutIfNeeded()

Layoutifneeded will force redrawing and block the main thread. After waiting for the reloaddata of tableview to update the layout, the subsequent code of layoutifneeded will be carried out. The disadvantage is that it will block the main thread and cause unnecessary jamming.

Base note two: call DispatchQueue. after reloadData. main. Async method

realization:

        self.tableView?.reloadData()
        DispatchQueue.main.async {
            self.tableView?.scrollToRow(at: IndexPath.init(row: self.selectedIndex, section: 0), at: .none, animated: true)
        }

Dispatchqueue main. Async waits for the main thread to be idle (after reloadData, not doing other operations on the base note). Even if tableView is updated after reloadData, it will not block the main thread and recommend this method.

Method 3: uiview The middle note is called reloadData in animate.

realization:

        UIView.animate(withDuration: 0.25) {
            self.tableView?.reloadData()
        } completion: { (isFinish) in
            if isFinish {
                self.tableView?.scrollToRow(at: IndexPath.init(row: self.selectedIndex, section: 0), at: .none, animated: true)
            }
        }

UIView. The base note is that animate uses completion to wait for the animation operation to complete the reloadData.