解析NSManagedObjectContext后台线程并解决“不同的上下文”问题

时间:2012-06-24 17:19:03

标签: objective-c core-data ios5 nsmanagedobject uimanageddocument

我正在尝试解析XML文档,并使用后台队列将其数据存储在Core Data存储中。我正在使用iOS 5中引入的新嵌套UIManagedObjectContext概念。

我已经为NSManagedObject公司添加了一个新类别,该公司处理公司特定数据的解析:

- (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"];
            ...

这就是我称之为此方法的方式:[company parseAttributesFrom:xmlStr inManagedObjectContext:self.managedDocument.managedObjectContext]; 请注意,即使我将托管对象上下文作为参数传递给方法,我的问题也没有改变。

当我运行代码时,它崩溃了我将annualPeriod设置为公司的位置,并显示错误消息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];

当代码在相同的背景构思中运行时,我很难理解为什么错误应与不同的上下文相关。我将不胜感激任何帮助!

2 个答案:

答案 0 :(得分:1)

我认为,原因是IBCompany *company = self;位于您传递的context中,然后您在另一个上下文中设置新连接。

这就是原因。

答案 1 :(得分:1)

你可能不这样做:

context.parentContext = self.managedObjectContext;

如果你在这里使用UIManagedDocument:

[company parseAttributesFrom:xmlStr inManagedObjectContext:self.managedDocument.managedObjectContext];

这是因为UIManagedDocument已经使用了嵌套的上下文,而self.managedDocument.managedObjectContext已经设置了它的父上下文。现在你要把它换掉,这样你就可以破坏它。

以下是UIManagedDocument Class Reference的引用。

  

为了支持异步数据写入,Core Data实际上使用了一对   嵌套的托管对象上下文。父上下文是在a上创建的   私有线程,在主线程上创建子上下文。您   从managedObjectContext属性中获取子上下文。