0

j'ai quelques grandes données dans mon magasin de base de données Comment puis-je charger ces données en fil d'arrière-plan?comment charger les données de base en fil de fond

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 besoin d'ajouter la charge de données de base en fil d'arrière-plan, puis mettre à jour mon tableView

Répondre

1

D'abord, vous devez mettre à l'esprit qu'un managedObjectContext fonctionne sur un seul fil. Et vous devez accéder/modifier les objets chargés sur le même thread.

Dans votre cas, vous allez interagir avec les objets que vous allez charger sur le thread principal. Par exemple, les objets de base de données chargés vont remplir un tableView et cela doit être fait sur le thread principal. Cela force le managedObjectContext à être de MainContextType qui s'exécute sur le thread principal.

http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/CoreData/Articles/cdConcurrency.html

Vous ne devriez pas avoir peur de courir le NSFetchedResultsController sur le thread principal car il charge les objets en lots. Cependant, vous n'utilisez pas le contrôleur FetchedResults comme il se doit. Vous ne devriez pas avoir ces deux lignes dans votre code.

personalArray = fetchResultController.fetchedObjects! 
self.tableView.reloadData() 

Vous devez accéder à l'objet chargé en utilisant cette méthode fetchResultController .objectAtIndexPath(indexPath).

Voici un exemple de la façon d'utiliser les 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){ 
     .... 
    } 

} 
+0

merci, mais si j'ai les 32k lignes de données de base (chargement de la base en NSFetchedResultsController prend plusieurs secondes, et je veux ajouter la recherche dans cette base) et je dois accélérer la charge de données de base ce que je dois faire? Puis-je ajouter plus de relations aux données de base et essayer de charger la base via des relations par groupes ou cela prendra aussi cette fois-ci? – Skie

+0

Cela dépend vraiment de ce que vous essayez de faire ... Vous devriez essayer d'optimiser vos requêtes. Utilisez l'indexation. Mais placer NSFetchedresultscontroller dans un contexte d'arrière-plan est un cauchemar, car il n'est pas destiné à être utilisé de cette façon. – ELKA