Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 the 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];  
}
like image 962
marchinram Avatar asked Jan 27 '11 13:01

marchinram


1 Answers

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.

like image 96
Yuji Avatar answered Oct 18 '22 13:10

Yuji