Search code examples
iosiphonecore-datansmanagedobjectcontext

Parent/Child NSManagedObjectContext not working


I'm having some trouble with Parent Child NSManagedObjectContext. The issue is that I want to use a child NSManagedObjectContext in my EventsPlanner class to create a random event. If you notice it works if you save directly to the main NSManagedObjectContext, but I want to use the child and update to the parent.

If you see pressing the '+' button adds a new event but it looks empty.

I'm added the example project --> https://dl.dropbox.com/u/63377498/ParentChildExperiment.zip

Creating the child NSManagedObjectContext:

- (NSManagedObjectContext *)managedObjectContext
{
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [_managedObjectContext setUndoManager:nil];
    [_managedObjectContext setParentContext:appDelegate.managedObjectContext];
    return _managedObjectContext;
}

Saving:

Event *event = [[Event alloc] initWithEntity:self.eventEntity insertIntoManagedObjectContext:nil];
event.title = ...;
event.location = ...;
event.timeStamp = ...;

[self.managedObjectContext insertObject:event];

[self.managedObjectContext performBlock:^{

NSError *childError = nil;
if ([self.managedObjectContext save:&childError]) {
    [self.managedObjectContext.parentContext performBlock:^{

        NSError *parentError = nil;

        if (![self.managedObjectContext.parentContext save:&parentError]) {
            NSLog(@"parent error: %@", [parentError description]);
            abort();

        }                        
    }];
} else {
    NSLog(@"child error: %@", [childError description]);
    abort();
}}];

Thanks!


Solution

  • I cannot give you the exact reason why this does not work, but the problem seems to be that you create the Event entity without a managed object context, and add it the MOC later:

    // Create random object
    Event *event = [[Event alloc] initWithEntity:self.eventEntity insertIntoManagedObjectContext:nil];
    event.title = ...;
    event.location = ...;
    event.timeStamp = ...;
    
    // Insert object
    [self.managedObjectContext insertObject:event];
    

    If you change this to

    Event *event = [[Event alloc] initWithEntity:self.eventEntity
                  insertIntoManagedObjectContext:self.managedObjectContext];
    event.title = ...;
    event.location = ...;
    event.timeStamp = ...;
    

    then the new events are displayed correctly in the table view.