简体   繁体   English

UI冻结在tableview reloadData()上

[英]UI freezes on tableview reloadData()

I have simple dictionary project with over 35000 records in Realm model. 我有一个简单的字典项目,在Realm模型中有35000多个记录。 When searching word from these records looking a little bit freeze in keyboard tapping. 从这些记录中搜索单词时,键盘敲击看起来有些冻结。 I think freeze going when I update my tableview with new records. 我认为用新记录更新表视图时会冻结。

import UIKit
import RealmSwift

class TestTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate {
    @IBOutlet weak var searchBar: UISearchBar!
    @IBOutlet weak var tableView: UITableView!
    let realm = try! Realm()
    var myRealmObject: Results<MyRealmObject>!

    override func viewDidLoad() {
        super.viewDidLoad()
        myRealmObject = realm.objects(MyRealmObject.self).sorted(byKeyPath: "german", ascending: true)
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myRealmObject.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = myRealmObject[indexPath.row].german
        return cell
    }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        myRealmObject = realm.objects(MyRealmObject.self).filter("german beginswith[cd] %@", searchText)
        print("Objects count - ", myRealmObject.count)
//        self.tableView.performSelector(onMainThread: Selector("reloadData"), with: nil, waitUntilDone: true)
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
}

If comment self.tableView.reloadData() and print result of Realm objects in console working without freezes. 如果注释self.tableView.reloadData()并在控制台中打印Realm对象的结果而不会冻结。 How I can perform my tableview.reload Data() ? 如何执行tableview.reload Data()?

Your keyboard is freezing coz you are performing filter on main thread which is taking time to operate on 35000 objects..As per my understanding, you need to put the below line in a background thread or use GCD to execute it asynchronously 您的键盘冻结了,您正在对主线程执行筛选,这需要花费一些时间才能对35000个对象进行操作。据我的理解,您需要将以下行放在后台线程中或使用GCD异步执行

 myRealmObject = realm.objects(MyRealmObject.self).filter("german beginswith[cd] %@", searchText)

Create a serial queue 创建一个串行队列

private let serialQueue =
  DispatchQueue(label: "com.example.searchQueue", attributes: .serial)

and then use the below code in your textDidChange 然后在您的textDidChange使用以下代码

serialQueue.async { [weak self] in
  guard let self = self else {
    return
  }
  // put your filter logic in here
  //self.myRealmObject = self.realm.objects(MyRealmObject.self).filter("german beginswith[cd] %@", searchText)

  DispatchQueue.main.sync { [weak self] in
    self?.tableView.reloadData()
  }
}

However, there is something more that you need to consider. 但是,您还需要考虑其他事项。 When user is typing real fast, it is worthwhile considering cancelling previous tasks before starting a new one or probably use asyncAfter 当用户真正快速键入时,值得考虑在开始新任务之前或使用asyncAfter之前取消先前的任务

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM