首页 > 解决方案 > 如何在不阻塞用户交互的情况下执行 tableView.reloadData()

问题描述

我使用 searchBar 在产品列表中搜索并在 tableView 中显示结果,我希望每个角色都开始新的搜索之旅我已经通过某种异步队列来搜索全局队列中的产品列表并更新500 毫秒后 mainQueue 中的 tableView。

问题是,在重新加载表格视图时,用户交互会阻塞,并且用户无法在表格视图完成之前输入新字符

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(searchOnProducts), object: nil)
    self.searchKeyWord = searchText
    self.perform(#selector(searchOnProducts), with: nil, afterDelay: 0.0)
}

@objc func searchOnProducts() {
    DispatchQueue.global().async {
        let returnedProducts = DataHolder.getProductsWithSearch(self.searchKeyWord)
        let productsRef: ThreadSafeReference<Results<Product>>?
        if returnedProducts != nil && returnedProducts!.count != self.searchProducts.count {
            productsRef = ThreadSafeReference(to: returnedProducts!)
        } else if returnedProducts == nil && self.searchProducts.count != 0 {
           productsRef = nil
        } else {
            return
        }
        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500), execute: {
            if productsRef != nil {
                let realm = try! Realm()
                guard let products = realm.resolve(productsRef!) else {
                    return
                }
                self.searchProducts = Array(products)
            } else {
                self.searchProducts.removeAll()
            }
            self.searchTV.reloadData()
        })
    }
}

标签: iosswift

解决方案


您正在主线程上的 RealmDB 上工作。您可能也应该将其移至全局队列。然后只调用reloadData()主线程。

编辑:在您的cellForRow,您还应该访问全局队列中的结果数组,然后更新主线程上的单元格内容。这样,您应该希望能够避免收到的线程错误。

另外:您是否尝试过分析您的应用程序?这应该让您更好地了解哪些代码行需要很长时间。当您创建表格视图单元格时,您可能会做任何其他耗时的事情吗?


推荐阅读