NSFetchedResultsController: Fetch in a background thread

后端 未结 3 1830
无人共我
无人共我 2020-12-16 03:02

I have a more or less basic UITableViewController with a NSFetchedResultsController. The UITableViewController is pushed onto the

相关标签:
3条回答
  • 2020-12-16 03:30

    The general rule with Core Data is one Managed Object Context per thread, and one thread per MOC. With that in mind you need to perform the fetch for the Fetched Results Controller on the main thread, as this is the thread that will be interacting with the FRC's Managed Objects. (See Core Data Programming Guide - Concurrency with Core Data)

    If you are having performance issues with the animation you should probably look at ways to ensure that the fetch is performed before or after the view is pushed. Normally you would perform the fetch in the view controller's viewDidLoad:, and the navigation controller wouldn't push the view until the fetch was complete.

    0 讨论(0)
  • 2020-12-16 03:37

    TL;DR; There is no good reason to use a context on the main queue.

    can use NSFetchedResultsController to fetch data in background

    Absolutely. NSFetchedResultsController can be used with a private queue context. It is, in fact, quite happy and performant when doing so. There is a bug that prevents NSFetchedResultsController from using it's cache when it's using a private queue, but the cache does not win you as much as it did in iOS 3.0. Set a cacheName of nil and you will be fine.

    1. Create a context with NSPrivateQueueConcurrencyType. Preferably not the one you use for IO.

    2. Create the fetched results controller with that context, and a cache name of nil.

    3. Perform your initial fetch from within a performBlock: block:

     [[[self fetchedResultsController] managedObjectContext] performBlock:^{
        NSError *fetchError = nil;
        if (![self fetchedResultsController] performFetch:&error]){
            /// handle the error. Don't just log it.
        } else {
            // Update the view from the main queue.
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                [tableView reloadData];
             }];
        }
     }];
    

    4. All of your delegate callbacks will now happen from the context's queue. If you are using them to update views, do so by dispatching to the main queue like you see above.

    5. ...

    6. Profit!

    You can read more about this here.

    0 讨论(0)
  • 2020-12-16 03:39

    You can go through this very nice post on Core Data with Multi-Threaded behavior.

    Hope it helps..!!

    0 讨论(0)
提交回复
热议问题