Reputation: 11
I have this code to search through different tables, my problem is that I cannot interact with the UI until the las fetch request is executed. If I search for specific value and the result is in "Table2" the tableView updates fine but cannot interact with it until it finishes searching the last table. The func loadData() just takes a few milliseconds to execute and exit and the fetches are executing in a different thread. I don't know what's wrong with this code, any help or advice? The total amount of records in all tables is about 5 millions, it takes some time to search through all of them, that's why I don't want to keep the user waiting if some results are available before it finishes searching the entire db.
func loadData () {
let tablas = ["Table1", "Table2", "Table3", "Table4", "Table5", "Table6", "Table7", "Table8", "Table9", "Table10", "Table11"]
let managedContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
managedContext.parentContext = self.moc
for tbl in tablas {
managedContext.performBlock {
let fetchRequest = NSFetchRequest(entityName: tbl)
let predicate = NSPredicate(format: "name CONTAINS %@", self.filter)
fetchRequest.predicate = predicate
fetchRequest.resultType = NSFetchRequestResultType.ManagedObjectIDResultType
fetchRequest.fetchLimit = 50
fetchRequest.fetchBatchSize = 10
do {
let results = try managedContext.executeFetchRequest(fetchRequest) as! [NSManagedObjectID]
if results.count != 0 {
self.resultArray.appendContentsOf(results)
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
}
}
} catch let error as NSError {
dispatch_async(dispatch_get_main_queue()) {
let errorAlert = UIAlertController(title: "Error!!!", message: error.localizedDescription, preferredStyle: .Alert)
errorAlert.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
self.presentViewController(errorAlert, animated: true, completion: nil)
}
}
}
}
}
Upvotes: 1
Views: 66
Reputation: 726
The UI handles most of its process in the main thread. If you have a major process, don't run it on the main thread synchronously. You can run it asynchronously on the main thread.
The code to asynchronously run on main thread:
dispatch_async(dispatch_get_main_queue(), {
// RUN CODE OVER HERE
})
Upvotes: 0
Reputation: 2461
Here are a few links to help you with planning your code
UITableView Load Data from JSON
Refreshing uitableview asynchronously after Core Data loaded
25 ios app performance tips tricks (Ray Wenderlich)
Upvotes: 1