Objective c 在NSManagedObjectContext后台线程中进行解析,并出现问题;“不同的语境”;

Objective c 在NSManagedObjectContext后台线程中进行解析,并出现问题;“不同的语境”;,objective-c,core-data,ios5,nsmanagedobject,uimanageddocument,Objective C,Core Data,Ios5,Nsmanagedobject,Uimanageddocument,我试图解析XML文档,并使用后台队列将其数据存储在核心数据存储中。我正在使用iOS5中引入的新嵌套UIManagedObjectContext概念 我已向我的NSManagedObject公司添加了一个新类别,该类别处理公司特定数据的解析: - (void)parseAttributesFrom:(NSString*)xmlStr inManagedObjectContext:(NSManagedObjectContext*)managedObjectContext

我试图解析XML文档,并使用后台队列将其数据存储在核心数据存储中。我正在使用iOS5中引入的新嵌套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设置为company时,代码崩溃,错误消息为NSInvalidArgumentException:
“非法尝试在不同上下文中的对象之间建立关系”“company”“。”(source=我认为,这是因为
IBCompany*company=self;
在您传递的
上下文中,然后您在另一个上下文中设置了新连接

这就是原因。

您不能这样做:

context.parentContext = self.managedObjectContext;
如果您在此处使用UIManagedDocument:

[company parseAttributesFrom:xmlStr inManagedObjectContext:self.managedDocument.managedObjectContext];
这是因为UIManagedDocument已经使用嵌套上下文,而self.managedDocument.managedObjectContext已经设置了其父上下文。现在您正在交换它,通过这样做,您可以中断工作

这里有一段引用自

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


你说得对,两个托管对象都有不同的上下文。我通过在后台上下文中重新蚀刻公司托管对象解决了这个问题。我的后台代码现在可以工作了。谢谢你,Nikita!
[company parseAttributesFrom:xmlStr inManagedObjectContext:self.managedDocument.managedObjectContext];