2

I'm trying to create a new instance of NSManagedObjectContext so that I can perform a fetch request in a thread other than the main one. As I understand it each thread needs it's own instance although they can share stores.

My app is a core data document based app.

Having read a bit here I've got this code:

NSManagedObjectContext *managedObjectContextForThread = nil;
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];

if (coordinator != nil) {
    managedObjectContextForThread = [[NSManagedObjectContext alloc] init];
    [managedObjectContextForThread setPersistentStoreCoordinator:coordinator];
    [managedObjectContextForThread setUndoManager:nil];
}

It runs but when I perform the fetch I get no results, I suspect because the NSPersistentStoreCoordinator isn't getting setup correctly.

How should I be setting that store coordinator to work with my main store? Or is there something else I'm missing here?

Community
  • 1
  • 1
Mark Wheeler
  • 587
  • 2
  • 6
  • 19

2 Answers2

5

Apple's 'typically recommended approach' is to share one persistent store coordinator among contexts. Ideally you would already have a reference to your app's main managed object context, and use that context's persistent store coordinator.

NSManagedObjectContext *managedObjectContextForThread = [[NSManagedObjectContext alloc] init];;
[managedObjectContextForThread setPersistentStoreCoordinator:myMainContext.persistentStoreCoordinator];

Take a look at "Concurrency With Core Data" from Apple's Core Data Programming Guide

ChrisH
  • 4,468
  • 2
  • 33
  • 42
  • 1
    There's nothing wrong with multiple persistent store coordinators in general. But each new PSC is a completely new dataspace. You do want to stick to one single PSC for each logical datastore. But I often have multiple, independent Core Data stacks in the same program, but that have nothing to do with each other.The code posted here is correct, I just have a quibble with the explanation. – Hal Mueller Mar 21 '13 at 17:23
  • Fair enough. Apple's guide says one shared PSC is "...the typically-recommended approach." so I'll edit my answer accordingly. – ChrisH Mar 21 '13 at 17:30
  • Ah so it's ok (safe) to use that MOC to get it's persistentStoreCoordinator in a thread? – Mark Wheeler Mar 21 '13 at 17:39
  • Great thanks! Spent way too long trying to avoid doing the correct thing :) – Mark Wheeler Mar 21 '13 at 17:50
  • If you're not worried about running your app on iOS 4.x you might want to look into the child MOC concepts that were introduced in iOS5. Depending on your situation they can make your life easier too. Check this article: http://www.cocoanetics.com/2012/07/multi-context-coredata/ – ChrisH Mar 21 '13 at 17:57
  • This one's a Mac app, will take a look – Mark Wheeler Mar 21 '13 at 18:05
0

You have to add the persistent store to the store coordinator, then add the persistent store the managed object context.

if ( [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:0 URL:storeUrl options:options error:&error] ) {
    managedObjectContextForThread = [[NSManagedObjectContext alloc] init];
    [managedObjectContextForThread setPersistentStoreCoordinator:coordinator];
}
else {
// investigate 'error'
}
Mike D
  • 4,938
  • 6
  • 43
  • 99