0

У меня есть некоторые большие данные в моем хранилище основных данных Как я могу загрузить эти данные в фоновом потоке?Как загрузить основные данные в фоновом потоке

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

мне нужно добавить нагрузки ядро ​​данных в фоновом потоке, а затем обновить мой Tableview

ответ

1

Во-первых, вы должны положить в виду, что managedObjectContext работает на одном потоке. И вы должны получить доступ/отредактировать загруженные объекты в том же потоке.

В вашем случае вы будете взаимодействовать с объектами, которые вы собираетесь загрузить по основному потоку. Например, загруженные объекты базы данных заполнят tableView, и это должно быть сделано в основном потоке. Это заставляет managedObjectContext быть MainContextType, который работает в основном потоке.

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

Вы не должны бояться запуска NSFetchedResultsController на главном потоке, поскольку он загружает объекты в пакетном режиме. Однако вы не используете контроллер FetchedResults, как следует. Вы не должны иметь эти две строки в своем коде.

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

Вы должны получить доступ к загруженному объекту, используя этот метод fetchResultController .objectAtIndexPath(indexPath).

Это пример того, как использовать 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

спасибо, но если у меня есть 32k строк в основных данных (загрузка базы в NSFetchedResultsController занимает несколько секунд, и я хочу, чтобы добавить поиск в эта база), и мне нужно ускорить загрузку основных данных, что я должен делать? могу ли я добавить больше отношений к основным данным и попытаться загрузить базу через отношения по группам, или это тоже займет это время? – Skie

+0

Это действительно зависит от того, что вы пытаетесь сделать ... Вы должны попытаться оптимизировать свои запросы. Используйте индексирование. Но включение NSFetchedresultscontroller в фоновый контекст - это кошмар, потому что он не предназначен для использования таким образом. – ELKA

 Смежные вопросы

  • Нет связанных вопросов^_^