Reputation: 111
i have some big data in my Core Data store how can i load this data in background thread?
func connectionCoreData() {
let fetchRequest = NSFetchRequest<PersonalClass>(entityName: "PersonalBase")
let sortDescriptor = NSSortDescriptor(key: "personName", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
if let managerObjectContext = (UIApplication.shared.delegate as? AppDelegate)?.managedObjectContext {
fetchResultController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managerObjectContext, sectionNameKeyPath: nil, cacheName: nil)
fetchResultController.delegate = self
do {
try fetchResultController.performFetch()
personalArray = fetchResultController.fetchedObjects!
self.tableView.reloadData()
} catch {
print(error)
}
}
}
i need add core data load in background thread and then update my tableView
Upvotes: 1
Views: 2007
Reputation: 735
First, you should put in mind that a managedObjectContext runs on a single thread. And you should access/edit the loaded objects on the same thread.
In your case, you will interact with the objects that you are going to load on the main thread. For example, the loaded database objects will fill a tableView
and this should be done on the main thread. This forces the managedObjectContext to be of MainContextType which runs on the main thread.
You should not be afraid of running the NSFetchedResultsController on the main thread because it loads the objects in batches. However, you aren't using the FetchedResults Controller as it should. You shouldn't have these two lines in your code.
personalArray = fetchResultController.fetchedObjects!
self.tableView.reloadData()
You should access the loaded object using this method fetchResultController .objectAtIndexPath(indexPath)
.
This is an example of how to use the NSFetchedResultsController
class ViewController: UITableViewController NSFetchedResultsControllerDelegate{
lazy var fetchedResultsController: NSFetchedResultsController = {
let fetchRequest = ... //Create the fetch request
let sortDescriptor = ... //Create a sortDescriptor
let predicate = ...//Create the predicate if you want to filter the results
fetchRequest.predicate = predicate
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: mainContext, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
return fetchedResultsController
}()
override fun viewDidLoad(){
super.viewDidLoad()
do {
try self.fetchedResultsController.performFetch()
}catch {
print(error)
}
}
func controllerWillChangeContent(controller: NSFetchedResultsController) {
tableView.beginUpdates()
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch (type) {
case .Insert:
if let indexPath = newIndexPath {
tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
break;
case .Delete:
if let indexPath = indexPath {
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
break;
case .Update:
if let indexPath = indexPath {
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
}
break;
case .Move:
if let indexPath = indexPath, newIndexPath = newIndexPath {
tableView.moveRowAtIndexPath(indexPath, toIndexPath: newIndexPath)
}
break;
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let sections = fetchedResultsController.sections {
let sectionInfo = sections[section]
return sectionInfo.numberOfObjects
}
return 0
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let obj = fetchedResultsController.objectAtIndexPath(indexPath){
....
}
}
Upvotes: 2