Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSFetchedResultsController performFetch on background thread

I have to perform a fetch via NSFetchedResultsController on a background thread.

My current solution is structured like that:

dispatch_queue_t fetchQueue = dispatch_queue_create("backgroundfetching", NULL);

dispatch_async(fetchQueue,^{
    // 1. Create NSManagedObjectContext
    // 2. Create NSFetchRequest
    // 3. Create NSFetchedResultsController
    // 4. PerformFetch

    dispatch_async(dispatch_get_main_queue(),^{
        [[self table] reloadData];
    });
});

dispatch_release(fetchQueue);

My first tests ran well but is that the appropriate way?

like image 974
Florian Mielke Avatar asked Aug 01 '11 12:08

Florian Mielke


People also ask

How does the nsfetchedresultscontroller cache data?

When you initialize an instance of NSFetchedResultsController, you typically specify a cache name. (If you do not specify a cache name, the controller does not cache data.) When you create a controller, it looks for an existing cache with the given name:

What is a fetched results controller?

A controller that you use to manage the results of a Core Data fetch request and to display data to the user. While table views can be used in several ways, fetched results controllers primarily assist you with a primary list view.

How does the controller notify the delegate when the result changes?

The controller notifies the delegate when result objects change location or when sections are modified (see NSFetchedResultsControllerDelegate ). You typically use these methods to update the display of the table view.


2 Answers

Since the fetched results controller is intended to control the data that defines a tableview, it belongs on the foreground thread/operation that the UI runs on. It's rather pointless to put it on a background thread as you would lose all the advantages of using it in the first place.

I would also be concerned about the effects of sending the FRC delegate messages across asynchronous threads. I'm not sure how reliable that would be.

Having said all that, the sketch of your implementation looks fine as far as it goes.

like image 147
TechZen Avatar answered Dec 07 '22 12:12

TechZen


I believe there is something fundamentally wrong with this approach, as you're sharing managed objects across threads (you're fetching objects on one thread and referencing them on your main thread). In practice it will work, but will sometimes lead to crashes. Because Apple makes it clear that the only ways to share managed objects across threads is using the objectWithID: method or the MOCDidSave notifications.

From the Core Data Programming Guide:

You fetch in one managed object context on a background thread, and pass the object IDs of the fetched objects to another thread. In the second thread (typically the application's main thread, so that you can then display the results), you use the second context to fault in objects with those object IDs (you use objectWithID: to instantiate the object).

like image 25
samvermette Avatar answered Dec 07 '22 13:12

samvermette