Ios 在UITableView中删除行花费太多时间
我正在编写一个程序,其中包含40k(40000)个项目的数组,并在UITableView中显示它,搜索表应该过滤并仅显示搜索结果 问题是一次删除多行(例如30000+行)大约需要10-20秒,并且无法使用。你能提出解决这个问题的建议吗 (Ios 在UITableView中删除行花费太多时间,ios,swift,uitableview,Ios,Swift,Uitableview,我正在编写一个程序,其中包含40k(40000)个项目的数组,并在UITableView中显示它,搜索表应该过滤并仅显示搜索结果 问题是一次删除多行(例如30000+行)大约需要10-20秒,并且无法使用。你能提出解决这个问题的建议吗 (tableview.reloadData()不适合) var allProducts=[Product]() @ibvar searchTableView:UITableView! @IBOutlet弱var searchTextField:UITextFiel
tableview.reloadData()
不适合)
var allProducts=[Product]()
@ibvar searchTableView:UITableView!
@IBOutlet弱var searchTextField:UITextField?
var searchResults=[Product]()
枚举操作{
案例插页
案例忽略
案例移除
}
重写func viewDidLoad(){
super.viewDidLoad()
searchTextField?.addTarget(self,action:#选择器(ViewController.textFieldDidChanged(:)),for:.editingChanged)
DBBrain().getAllAlcProducts(){[weake self]中的产品
self?.allProducts=产品
}
}
func textFieldDidChanged(\发送方:UITextField){
DispatchQueue.global(qos:.userInitiated).async{[weak self]在中
让text=sender.text!。小写()
让res=self!.allProducts.filter({$0.name.lowercased().contains(text)})
如果self?.searchTextField?.text!=nil&&text==self!.searchTextField!.text{
如果let values=self?.getIndexes(forResults:res){
self?.searchResults=res
self?.updateTable(操作:value.0,索引:value.1)
}
}
}
}
private func getindex(forResults产品:[Product])->(操作,[indexath]){
变量索引=[indexath]()
var action=action.Ignore
如果searchResults.count>products.count{
var newCounter=0
对于0..中的x,您永远不应该有一个包含30k+单元格的表。这是一个荒谬的内存使用。您应该为rowsForSection委托方法中的单元格数设置最大限制
获取结果的计数,如果计数大于30左右(即使这是一个很大的数字),则将其设置为30
它很可能也有一个超大阵列。这会占用大量内存,即使你没有为它们制作单元。你的应用程序会冻结10-20秒吗?如果是这样,你应该确保删除是异步执行的。你为什么要一次删除30000行?你需要用更多的rel更新你的问题浏览有关您正在做的事情的信息。也许您可以阅读“无限列表”技术。它可能会让您了解如何为UITableView(或任何列表)处理大量元素考虑什么是屏幕内的内容和改变后将要在屏幕上显示的东西。在表视图中向用户呈现40000个项目是个坏主意。即使删除30000个项目之后,也没有用户想要滚动剩下的10000个。认真考虑重构数据模型并以更结构化的方式呈现数据。这很有用,也很有用。@Matt Le Fleur是的,它被冻结了。列表排序(数据源)只需不到1秒的时间就可以实现异步,但要准确地更新UI需要花费所有的时间,我无法在后台执行。是的,谢谢你和所有其他人,我想我会尝试重新设计算法以显示更少的单元格,并将其发布在这里……可能对任何人都有用)
var allProducts = [Product]()
@IBOutlet weak var searchTableView: UITableView!
@IBOutlet weak var searchTextField: UITextField?
var searchResults = [Product]()
enum Action{
case Insert
case Ignore
case Remove
}
override func viewDidLoad() {
super.viewDidLoad()
searchTextField?.addTarget(self, action: #selector(ViewController.textFieldDidChanged(_:)), for: .editingChanged)
DBBrain().getAllAlcProducts() { [weak self] products in
self?.allProducts = products
}
}
func textFieldDidChanged(_ sender: UITextField){
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
let text = sender.text!.lowercased()
let res = self!.allProducts.filter({ $0.name.lowercased().contains(text) })
if self?.searchTextField?.text != nil && text == self!.searchTextField!.text!{
if let values = self?.getIndexes(forResults: res){
self?.searchResults = res
self?.updateTable(action: values.0, indexes: values.1)
}
}
}
}
private func getIndexes(forResults products: [Product]) -> (Action, [IndexPath]){
var indexes = [IndexPath]()
var action = Action.Ignore
if searchResults.count > products.count{
var newCounter = 0
for x in 0..<searchResults.count {
if products.isEmpty || searchResults[x].id != products[newCounter].id {
indexes.append(IndexPath(row: x, section: 0))
}else {
if newCounter < products.count - 1{
newCounter += 1
}
}
}
action = Action.Remove
}else if searchResults.count < products.count{
var oldCounter = 0
for x in 0..<products.count {
if searchResults.isEmpty || searchResults[oldCounter].id != products[x].id {
indexes.append(IndexPath(row: x, section: 0))
}else {
if oldCounter < searchResults.count - 1 {
oldCounter += 1
}
}
}
action = Action.Insert
}
return (action, indexes)
}
private func updateTable(action: Action, indexes: [IndexPath]) {
DispatchQueue.main.async { [weak self] in
if action != .Ignore {
if action == .Remove {
self?.searchTableView.beginUpdates()
self?.searchTableView.deleteRows(at: indexes, with: .fade)
self?.searchTableView.endUpdates()
}else if action == .Insert {
self?.searchTableView.beginUpdates()
self?.searchTableView.insertRows(at: indexes, with: .fade)
self?.searchTableView.endUpdates()
}
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchResults.count
}