I have researched a ton of posts regarding Core Data on background threads, and I feel like I understand (on paper) what needs to be going on. I guess we’ll see. I am working on migrating an existing OS X app to Core Data, and am having issues making new instances of my NSManagedObject on an async thread.
Here is a sample of the code I am running right after I have moved onto a background thread:
NSLog(@"JSON 1");
NSManagedObjectContext * context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:[[NSApp delegate] persistentStoreCoordinator]];
asset = (MTAssetInfo*)[NSEntityDescription insertNewObjectForEntityForName:@"Info" inManagedObjectContext:context];
NSLog(@"JSON 2");
The result is that the first log message (@"JSON 1") gets called 31 times, and the second one (@"JSON 2") is never called. The object isn’t being made and returned correctly.
The model for this Info entity is quite complex with a few transformable attributes that may or may not be setup correctly. The weird thing is that similar code run on the main thread and the main MOC works great. No issues.
EDIT – Some more context
The async call originates from here:
for (NSNumber *sectionID in sectionsToShow) {
dispatch_group_async(group, queue, ^{
MTAssetInfo *asset = [self assetWithRefID:[sectionID unsignedIntegerValue]];
if (asset != nil) {
[sectionsLock lock];
[sectionsTemp addObject:asset];
[sectionsLock unlock];
}
});
}
The assetWithRefID method never returns with an object because of the other code snippet. It never successfully pulls an NSManagedObject out of the context on the background thread.
You are going to have to provide more information to get real help, but I bet your problem is an error happening in the NSManagedDocument background thread.
I’d register a NSNotificationCenter for ALL messages (name:nil object:nil) and just print them out. I bet you see a status change or error message in there that is failing.
You might want to try a @try/@catch block around it just to see if exceptions are being thrown.
Maybe it will give you more to go on.
One other suggestion… Swizzling isn’t necessarily the right tool for production stuff, but it’s almost unbeatable for debugging. I have method-swizled several entire classes, so that it sends a detailed NSNotification before/after each invocation.
It has saved me tons of time, and helped me track down some wicked bugs. Now, when something is going on in CoreData, I take out my set of classes, link them in, and see all the detail I want.
I know that does not exactly answer you question, but hopefully it will put you on the track so you can provide some more information and get it all fixed.
If that’s too much for you, create a subclass and instantiate that, with a similar method for calling super. You can get a real idea of the entire flow pretty easily.