将 objects 从主队列中的 parent 上下文传递到私有队列中的 child

Passing objects from a parent context in main queue to a child in private queue

我在 class 中有一个 NSMutableArray 属性,其中我一直引用 NSManagedObjectContext 的一些托管 objects,我称之为 [=16] =] 并且关联到主队列。在同一个 class 中,我在私有队列中创建了一个 privateContext 并将其设置为 mainContext.

的 child

我想将属于 mainContextNSMutableArray (self.entities) 中的 objects 传递给它的 child privateContext,同时,一旦它们位于另一个数组 (self.tempEntities) 的 privateContext 中,就保留对此类 objects 的引用。我想保留这些引用,因为稍后我将在 privateContext 中插入新的 objects,并且我需要轻松地知道 privateContext 中那个时刻的 objects ] 来自其 parent mainContext.

我不确定这种做法是否正确:

for (MyEntity *entity in self.entities) { // this is main thread
   [self.privateContext performBlockAndWait: ^{
      [self.privateContext objectWithID:entity.objectID];
      [self.tempEntities addObject:entity];
    }];
}

否则以后会出现问题。或者有没有其他更好的方法来做到这一点?

谢谢

编辑: 在这种情况下,当 child 被保存时,parent 上下文将如何更新?我的意思是:在我的场景中,将 parent 中的 objects 传递给 child 上下文的目的是我需要在 child 上下文中比较它的新 objects 与从 parent 传递的那些。然后,也许我需要删除一些来自 parent 的 objects,and/or 替换一些来自 parent 的 objects child 中的新闻,and/or 将 child 中的一些新 objects 插入 parent。

调用 [self.privateContext save:nil]; 是否会将 parent 上下文中的所有 objects 替换为 child 中的 objects,或者如何处理合并?

再次感谢

您仍在后台线程中访问主线程对象,这是不允许的。这可能有效(如果它不触发自动获取),但在进入后台线程之前获取对象 ID 更安全。

NSManagedObjectID objectID = entity.objectID;
[self.privateContext performBlockAndWait: ^{
   MyEntity *bgEntity = [self.privateContext objectWithID:objectID]
   // do something with the entity, e.g. update it and save.
}];

确保您在块中的后台执行所有需要执行的操作。我会建议 不要 将这些对象分配给控制器(就像您使用 self.tempEntities 所做的那样),在那里它们再次可用于主线程。如果在主线程上访问它们,您的应用程序将崩溃。

另一个改进可能是只使用一个上下文。

 NSArray *objectIDs = [self.entities valueForKeyPath:@"objectID"];
 [self.privateContext performBlockAndWait ^{
    for (NSManagedObjectID *objectID in objectIDs) {
        MyEntity *bgEntity = [self.privateContext objectWithID:objectID];
        // process...
    }
 }];

至于更新主上下文:当您保存子上下文时,它所做的只是 "push up" 对父上下文的更改。父上下文现在知道更改,但当然它不会自动更新您的数组。

有两种途径:更复杂和冒险的一种是听NSManagedObjectContextObjectsDidChangeNotification。在通知处理程序中,您可以更新数组和 table 视图。尽管如此,这还是有风险的,因为没有内存或性能优化等。

更好:使用 NSFetchedResultsController 并实施 NSFetchedResultsControllerDelegate 方法来更新您的 table 或其他数据结构。您可以免费获得许多强大的功能。