Search code examples
objective-ccore-dataios5nsmanagedobjectuimanageddocument

Parsing in an NSManagedObjectContext background thread and issues with "different contexts"


I am trying to parse a XML document and store its data in a Core Data store using an background queue. I am using the new nested UIManagedObjectContext concept introduced in iOS 5.

I have added a new category to my NSManagedObject company, which handles the parsing of company specific data:

- (void)parseAttributesFrom:(NSString*)xmlStr 
             inManagedObjectContext:(NSManagedObjectContext*)managedObjectContext 
  {
  NSManagedObjectContext * context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

  context.parentContext = self.managedObjectContext;
  [context performBlock:^{

                IBCompany *company = self;
                [company setValue:[[[document.root childNamed:@"CoIDs"] childWithAttribute:@"Type" value:@"CompanyName"] value] forKey:@"companyName"];
            ...

This is how I call this method: [company parseAttributesFrom:xmlStr inManagedObjectContext:self.managedDocument.managedObjectContext]; Please note that my issue is unchanged, even if I pass the managed object context as a parameter to the method.

When I run the code, it crashes where I set the annualPeriod to the company with the error message NSInvalidArgumentException: 'Illegal attempt to establish a relationship 'company' between objects in different contexts (source = <IBEstPeriod: ...:

IBEstPeriod *annualPeriod = [NSEntityDescription insertNewObjectForEntityForName:@"IBEstPeriod" inManagedObjectContext:context];
[annualPeriod setCompany:company];

I am struggling to understand why the error should be related to different contexts when the code runs in the same background ideas. I would appreciate any help!!


Solution

  • I think, that reason is that IBCompany *company = self; is in the context you pass, and then you set the new connection in another context.

    That's the reason.