ios - 如何在不阻塞用户交互的情况下执行 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()
})
}
}
解决方案
您正在主线程上的 RealmDB 上工作。您可能也应该将其移至全局队列。然后只调用reloadData()
主线程。
编辑:在您的cellForRow
,您还应该访问全局队列中的结果数组,然后更新主线程上的单元格内容。这样,您应该希望能够避免收到的线程错误。
另外:您是否尝试过分析您的应用程序?这应该让您更好地了解哪些代码行需要很长时间。当您创建表格视图单元格时,您可能会做任何其他耗时的事情吗?
推荐阅读
- postgresql - postgresql 中的分区
- python - AttributeError:“Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst”对象没有属性“SRNE”
- python - 为什么我在使用 pytest 进行测试时收到 ModuleNotFoundError?
- python - 在一个 docker 容器中运行多个进程是否有意义?
- firebase - 如何在firebase身份验证中更改用户电话号码?
- java - 可以从其他容器创建 mysql 容器的转储吗?
- image - Slick js,如果幻灯片图像损坏,有没有办法过滤幻灯片?
- java - 如何将遗留的 spring jar(基于构造函数的注入和 xml 定义的 bean)导入 Quarkus
- javascript - 在 svg 代码中声明的样式标签会影响其他 svg 代码
- kotlin - Jetpack Compose:如何连接 2 个 LazyColumns