如何在后台线程中加载Core Data

时间:2016-11-14 02:23:26

标签: swift multithreading core-data nsfetchedresultscontroller dispatch-async

我的Core Data商店中有一些大数据 如何在后台线程中加载这些数据?

    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 个答案:

答案 0 :(得分: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){
       ....
    }

}