Ios 大uitableview(1000行)在重新加载数据()时冻结

Ios 大uitableview(1000行)在重新加载数据()时冻结,ios,swift,uitableview,Ios,Swift,Uitableview,我有一个大约1000行的UITableView。我还有一个计时器,每6秒运行一次,从web服务获取数据。每次我调用reloadData()时,都会有一个亮点——我的应用程序会明显冻结一小会儿。这在滚动时非常明显。 我试着只提取了大约400行,但光点消失了。有什么技巧可以在仍然获取1000行的情况下消除这个问题吗 var items: [Item] = [] Timer.scheduledTimer(withTimeInterval: 6, repeats: true) { [weak self

我有一个大约1000行的UITableView。我还有一个计时器,每6秒运行一次,从web服务获取数据。每次我调用reloadData()时,都会有一个亮点——我的应用程序会明显冻结一小会儿。这在滚动时非常明显。 我试着只提取了大约400行,但光点消失了。有什么技巧可以在仍然获取1000行的情况下消除这个问题吗

var items: [Item] = []

Timer.scheduledTimer(withTimeInterval: 6, repeats: true) { [weak self] _ in
   guard let strongSelf = self else { return }

   Alamofire.request(urlString, method: method, parameters: params) { response in
      // parse the response here and save it in array called itemsFromResponse
      OperationQueue.main.addOperation {
         strongSelf.items = itemsFromResponse
         strongSelf.itemsTableView.reloadData()
      }
   }
}
UITableViewDataSource代码:

extension ItemViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell", for: indexPath) 

        cell.textLabel?.text = items[indexPath.row].name

        return cell
    }
}

之所以会出现此问题,是因为您正在存储响应中的项,然后从相同的
操作队列
更新表视图,这意味着在更新数组时UI线程被阻塞。如果您不需要对任务进行细粒度控制(例如取消和高级调度,这里不需要),那么使用操作队列本身并不是安排任务的最佳方式。您应该改为使用
调度队列

为了解决问题,应该从后台完成处理程序更新数组,然后更新表

Timer.scheduledTimer(withTimeInterval: 6, repeats: true) { [weak self] _ in
   guard let strongSelf = self else { return }

   Alamofire.request(urlString, method: method, parameters: params) { response in
      // parse the response here and save it in array called itemsFromResponse
      strongSelf.items = itemsFromResponse
      // update the table on the main (UI) thread
      DispatchQueue.main.async {
         strongSelf.itemsTableView.reloadData()
      }
   }
}

您还应该寻找一种更有效的方法来获取新数据,因为每6秒重新加载整个数据集对于用户手机上的数据或CPU来说不是很有效。

问题是您每6秒重新加载数据,因此如果数据太大,则每6秒重新加载1000行。我建议您请求数据并比较是否有新数据,因此在这种情况下,您需要重新加载数据,或者只需请求刷新一次。例如:

var items: [Item] = []

Timer.scheduledTimer(withTimeInterval: 6, repeats: true) { [weak self] _ in
   guard let strongSelf = self else { return }

   Alamofire.request(urlString, method: method, parameters: params) { response in
      // parse the response here and save it in array called itemsFromResponse
      OperationQueue.main.addOperation {
         if(strongSelf.items != itemsFromResponse){
            strongSelf.items = itemsFromResponse
            strongSelf.itemsTableView.reloadData()
         }             
      }
  }

运行时间分析器以查找花费时间的内容。