Object's persistent store is not reachable from this NSManagedObjectContext's coordinator

2,040 views
Skip to first unread message

Mike

unread,
Jul 21, 2011, 2:39:26 PM7/21/11
to RestKit
Hi Blake and list,

My CoreData + RestKit app has been hitting the above error and I'm
having a hard time tracking down why.

The app uses its own core data NSManagedObjectContext for doing all of
its typical functions: populating table views, etc. I'm using Restkit
to make synchronization calls with an external API only when the user
clicks a button.

The Restkit call (loadObjectsAtResourcePath) pulls down the full
object graph from the server, updating whatever was currently stored
on the device.

When I make the call from my root view controller, it works fine.
However if I'm a few screens down in the navigation stack when I make
the call, the above error occurs after Restkit receives the server's
response. My RKObjectLoaderDelegate never gets notified of anything so
it seems the error is happening somewhere within the Restkit stack.

I have Restkit network logging enabled, and here are the last few
lines:

2011-07-21 20:29:22.750 MyApp[76291:207] D
restkit.network:RKResponse.m:105 NSHTTPURLResponse Status Code: 201
2011-07-21 20:29:22.750 MyApp[76291:207] D
restkit.network:RKResponse.m:106 Headers: { ... }
2011-07-21 20:29:22.751 MyApp[76291:207] T
restkit.network:RKResponse.m:107 Read response body:
2011-07-21 20:29:22.751 MyApp[76291:9007] D
restkit.network:RKObjectLoader.m:207 No object mapping provider, using
mapping provider from parent object manager to perform KVC mapping
2011-07-21 20:29:22.752 MyApp[76291:9007] *** Terminating app due to
uncaught exception 'NSInvalidArgumentException', reason: 'Object's
persistent store is not reachable from this NSManagedObjectContext's
coordinator'

I see this "no object mapping provider" warning regularly and things
seem to work, so I don't think that's the problem.

Can anyone give me some advice about what I'm doing wrong, or
somewhere I should look? I'm guessing that something is conflicting
with RestKit's CoreData object mapper.

Blake Watters

unread,
Jul 24, 2011, 8:08:41 PM7/24/11
to res...@googlegroups.com
The no object mapping provider is just an informational debug warning.

The persistent store coordinator error probably indicates that you are accessing a managed object context across thread boundaries. Core Data is seriously annoying about thread access and you have to be careful with your object instances and MOC references across threads. Check that you aren't retaining an object instance and then accessing it after a thread jump. RestKit tries to smooth a lot of this out for you, but its easy to get into the weeds. If you get a breakpoint on the crash, you should be able to figure out which object or MOC is causing the issue.

When you jump threads, you can refetch an object using the managed object ID to get a thread local version of it. The managedObjectContext method on RKManagedObjectStore always returns a thread-local MOC to work with, so you can fetch from there.

Mark Ramos

unread,
Oct 23, 2012, 1:05:03 AM10/23/12
to res...@googlegroups.com
Hi Blake,

So basically what we can do here is to verify the thread handling that we might have like 
dispatch_async calls.

Do you suggest that restkit calls should not be put inside dispatch_async calls? Here's a snippet of my code that usually crashes with the same error:


-(void) syncContactsViaRestKit{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *vmsgUserId = [defaults stringForKey:@"vmsgUserId"];
    BOOL initialSync = [defaults boolForKey:@"initialSync"];
    BOOL sync = [defaults boolForKey:@"sync_preferences"];

    if(initialSync){
        [defaults setBool:NO forKey:@"initialSync"];
        [defaults synchronize];
        HUD = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
        HUD.delegate = self;
        HUD.mode = MBProgressHUDModeIndeterminate;
    }

    if(sync){
        HUD.labelText = @"Synchronize Contacts...";
    }else{
        HUD.labelText = @"Retrieving Server Contacts...";
    }

    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        NSMutableArray *contacts;
        if (sync) {
            contacts = [self getPhoneContacts];
        }

        dispatch_async(dispatch_get_main_queue(), ^{

            if(sync){
                if(contacts == nil){
                    HUD.labelText = @"Cannot retrieve contacts...";
                    [HUD hide:YES afterDelay:1];
                    [CustomAlertView showCustomPop:CustomAlertViewTypeSingle inView:self.view WithFrame:self.view.frame Title:@"Alert" Message:@"Please allow app to retrieve contacts for sync via Settings app > Privacy > Contacts > App > On" actionButtonTitle:@"Ok" action:@selector(doSomething) cancelButtonTitle:nil];
                }else{
                    NSError *error = nil;
                    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:contacts options:NSJSONWritingPrettyPrinted error:&error];
                    if ([jsonData length] > 0 && error == nil) {
                        [self sendRestkitSyncRequestWithUserId:vmsgUserId withContactsPayload:jsonData];
                    }
                }
            }else{
                [self sendRestkitSyncRequestWithUserId:vmsgUserId withContactsPayload:nil];
            }

        });
    });
}


-(void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects{
    NSLog(@"Load collection of Contacts: %@", objects);
    NSLog(@"Object Size: %d", objects.count);

    NSArray *cont = [Contacts allObjects];
    for(Contacts *contact in cont){
        if(![objects containsObject:contact]){
            NSLog(@"Delete the contact : %@ withID: %@ ;because it is not anymore in the new list from server..",contact.name, contact.vmsgUserId);
            [[[[RKObjectManager sharedManager] objectStore] managedObjectContextForCurrentThread] deleteObject:contact];
        }
    }

    //Saving changes in MOC
    NSError* error = nil;
    [[[[RKObjectManager sharedManager] objectStore] managedObjectContextForCurrentThread] save:&error];

    [HUD hide:YES];
}


Here is a snippet of the crash report:

Object's persistent store is not reachable from this NSManagedObjectContext's coordinator
4 App 0x000ff889 -[RKManagedObjectStore objectWithID:] + 165
5 App 0x0010027d -[RKManagedObjectThreadSafeInvocation deserializeManagedObjectIDsForArgument:withKeyPaths:] + 905...


  1. 0 CoreFoundation 0x35da42a3 <redacted> + 163
  2. 1 libobjc.A.dylib 0x340b497f objc_exception_throw + 31
  3. 2 CoreData 0x3770ec29 <redacted> + 713
  4. 3 CoreData 0x37709897 <redacted> + 355
  5. 4 App 0x000ff889 -[RKManagedObjectStore objectWithID:] + 165
  6. 5 App 0x0010027d -[RKManagedObjectThreadSafeInvocation deserializeManagedObjectIDsForArgument:withKeyPaths:] + 905
  7. 6 App 0x00100521 -[RKManagedObjectThreadSafeInvocation deserializeManagedObjects] + 237
  8. 7 App 0x0010056d -[RKManagedObjectThreadSafeInvocation performInvocationOnMainThread] + 25
Reply all
Reply to author
Forward
0 new messages