Reputation: 33
I have simple dictionary project with over 35000 records in Realm model. 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. How I can perform my tableview.reload Data() ?
Upvotes: 1
Views: 1533
Reputation: 468
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
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
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
Upvotes: 1