美文网首页iOS/MacOS开发
UITableView reloadData异步刷新问题

UITableView reloadData异步刷新问题

作者: 苍眸之宝宝 | 来源:发表于2021-06-24 10:30 被阅读0次

简介:

  UITableView的reloadData是异步的,在调用该方法后,会继续执行其它代码(tableView的布局、cell的显示和高度计算等代理方法,或者自己的一些代码等),不会阻塞主线程;即reloadDate并不会等待tableview更新结束后才返回,而是立即返回。这样就会导致无法确定reloadData后完成的时机,无法在reloadData完成后及时的做其它操作(例如滚动到指定单元格);如果表中的数据比较大或者布局比较复杂,在一个run loop周期没执行完,这时,需要对tableview视图数据的操作,就会出问题了(例如滚动到指定单元格)。
问题代码如下:

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

怎样解决这个问题呢,即怎么获取reloadData完成的时机呢?有三种方法,这三种方法的实现和原理如下:

方法一:reloadData后调用layoutIfNeeded

实现:

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

  layoutIfNeeded会强制重绘,阻塞主线程,等待tableView的reloadData更新布局后,进行layoutIfNeeded的以后的代码,坏处是会阻塞主线程,造成不必要的卡顿。

方法二:reloadData后调用DispatchQueue.main.async方法

实现:

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

  DispatchQueue.main.async等待主线程空闲时(在reloadData后,不在主线程做其它操作),即使tableView进行reloadData更新布局后调用,不会阻塞主线程,推荐使用该方法。

方法三:UIView.animate中调用reloadData,结束后再进行其它操作

实现:

        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.animate利用completion等待动画操作reloadData完成后调用。

相关文章

网友评论

    本文标题:UITableView reloadData异步刷新问题

    本文链接:https://www.haomeiwen.com/subject/lzrwyltx.html