Пользовательский интерфейс зависает на табличном представлении reloadData () - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть простой проект словаря с более чем 35000 записей в модели Realm.При поиске слова из этих записей выглядят немного зависшими при нажатии клавиш.Я думаю, что остановка происходит, когда я обновляю свое табличное представление новыми записями.

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()
        }
    }
}

Если прокомментировать self.tableView.reloadData () и вывести результат объектов Realm в консоли, работающей без зависаний.Как я могу выполнить свои данные tableview.reload ()?

1 Ответ

0 голосов
/ 24 сентября 2018

Ваша клавиатура зависает, потому что вы выполняете фильтр в главном потоке, который требует времени для работы с 35000 объектов. Насколько я понимаю, вам нужно поместить строку ниже в фоновом потоке или использовать GCD для ее асинхронного выполнения

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

Создайте последовательную очередь

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

, а затем используйте приведенный ниже код в вашем 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()
  }
}

Однако есть еще кое-что, что вам нужноучитывать.Когда пользователь печатает очень быстро, стоит подумать об отмене предыдущих задач перед началом новой или, возможно, использовать asyncAfter

...