Reputation: 27275
So I've been reading stack for a while and I realize I need to make a background core data NSManagedObjectContext
as I'm loading a significant number of records and I want to not lock up the UI.
What I did was the following:
backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
NSPersistentStoreCoordinator *store = [[self managedObjectContext] persistentStoreCoordinator];
[backgroundContext setPersistentStoreCoordinator:store];
and in my function call I directly do:
self.flightsFRC = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:backgroundContext
sectionNameKeyPath:nil
cacheName:@"FlightRecords"];
My code is currently working but I feel like its "bad" else where I"m directly accessing the FRC without dealing with any synchronization or anything such as here where I iterate through the Fetched Results Controller.
FlightRecording *rec = [[[self flightsFRC] fetchedObjects] objectAtIndex:i];
Am I missing something? Should I be somehow loading records via a NSManagedObjectID
this seems "too easy"
Upvotes: 0
Views: 104
Reputation: 18477
You currently have your FRC pointing to the background context. Don't do that. Only point to a context on the main thread.
In order for your FRC to get notified of the changes, you actually need to merge the background context to your main thread context. Your CoreData stack object needs to register for notifications when the background context saves:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:nil];
Since the notification can be posted from other threads, we'll need to do a check when this triggers to make sure we are on the main thread. If we're already there, then we can call the mergeChangesFromContextDidSaveNotification
API on NSManagedObjectContext
.
- (void)contextDidSave:(NSNotification *)notification {
if (![NSThread isMainThread]) {
dispatch_async(dispatch_get_main_queue(), ^{
[self contextDidSave:notification];
});
} else {
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
}
}
Since your FRC is listening for changes when the data on main context changes, the FRC will then trigger its callbacks so that you can insert/delete/modify records in your tableview or collectionview.
EDIT:
It sounds like you may not be doing any changes on a background thread because you are not using the background context's performBlock:
or a private queue to do the work:
[backgroundContext performBlock:^{
// Do your work
NSError *error = nil;
BOOL success = [backgroundContext save:&error];
// error handling
}];
Upvotes: 1