Core Data background thread NSManagedObjectContext merging error
I'm writing an Ipad app that shows articles and downloads new articles in a separate NSOperation on a queue and inserts them into core data. Currently I have a separate context for the operation, created in the main method of the operation and using the same coordinator as th开发者_Python百科e main context. I use the same pattern that has been suggested alot of listening in that operation for NSManagedObjectContextDidSaveNotification and then calling mergeChangesFromContextDidSaveNotification on the main thread context. The problem is I'm getting this error:
2011-01-27 07:26:02.574 Zagazine[12298:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Object's persistent store is not reachable from this NSManagedObjectContext's coordinator'
*** Call stack at first throw:
(
0 CoreFoundation 0x3284b987 __exceptionPreprocess + 114
1 libobjc.A.dylib 0x31aca49d objc_exception_throw + 24
2 CoreData 0x3549d07b _PFRetainedObjectIDCore + 638
3 CoreData 0x3549cdfb - [NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:] + 14
4 CoreData 0x354bf85b -[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:] + 2170
5 CoreFoundation 0x327e9bbf -[NSObject(NSObject) performSelector:withObject:] + 22
6 Foundation 0x320fd795 __NSThreadPerformPerform + 268
7 CoreFoundation 0x328017dd __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 12
8 CoreFoundation 0x327d34fb __CFRunLoopDoSources0 + 194
9 CoreFoundation 0x327d2e5b __CFRunLoopRun + 230
10 CoreFoundation 0x327d2c87 CFRunLoopRunSpecific + 230
11 CoreFoundation 0x327d2b8f CFRunLoopRunInMode + 58
12 GraphicsServices 0x3094a4ab GSEventRunModal + 114
13 GraphicsServices 0x3094a557 GSEventRun + 62
14 UIKit 0x32c14329 -[UIApplication _run] + 412
15 UIKit 0x32c11e93 UIApplicationMain + 670
16 ArticleApp 0x0000233f main + 70
17 ArticleApp 0x000022f4 start + 40
)
terminate called after throwing an instance of 'NSException'
Program received signal: “SIGABRT”.
This interesting part is that this error only occurs the first time I launch the app after installing it. All subsequent launches after it's installed work fine. Does anyone know why this error is happening and why it would only happen on initial install.
Also, this is how I'm merging the context, this is called on background thread when it receives notification:
- (void)mergeChanges:(NSNotification *)notification {
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *mainContext = [appDelegate managedObjectContext];
// Merge changes into the main context on the main thread
[mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
withObject:notification
waitUntilDone:YES];
}
This interesting part is that this error only occurs the first time I launch the app after installing it. All subsequent launches after it's installed work fine. Does anyone know why this error is happening and why it would only happen on initial install.
My guess then is that the persistent store is not correctly associated to the file on the disk correctly at the first launch. The file backing the Core Data store does not materialize when you assign its URL to the persistent store coordinator. It only materializes when it is first saved.
And merging changes without having a backed file ready causes a lot of problems.
Try saving the context once from the main thread at the first launch very early in the execution, when the Core Data context is still empty, before creating the background thread. Hopefully that will solve your issue.
Did you have any other mergeChangesFromContextDidSaveNotification
notification being observed by any other context? If so, it might be the order you're notifying. It might be notifying to a context who doesn't know about the schema the changes are affecting to (aka, 'Object's persistent store is not reachable from this NSManagedObjectContext's coordinator').
精彩评论