将对象从主队列中的父上下文传递到专用队列中的子对象

时间:2015-09-27 15:32:41

标签: ios core-data concurrency nsmanagedobject nsmanagedobjectcontext

我在一个类中有一个NSMutableArray属性,我继续引用NSManagedObjectContext的一些托管对象,我称之为mainContext并且与主队列相关联。在同一个班级中,我在私人队列中创建privateContext,并将其设置为mainContext的子级。

我想将属于NSMutableArray的{​​{1}}(self.entities)中的对象传递给其子mainContext,同时,一旦这些对象位于另一个数组privateContext中(privateContext),请保留对这些对象的引用。我想保留这些引用,因为我稍后会在self.tempEntities中插入新对象,我需要很容易地知道privateContext中当时哪些对象来自其父privateContext }}

我不确定这样做是否正确:

mainContext

或者这会在以后引起任何问题。或者可能还有另一种更好的方法吗?

由于

编辑:保存子项时,在这种情况下如何更新父上下文?我的意思是:在我的场景中,传递给子上下文中父对象的目的是我需要在子上下文中将其新对象与从父对象传递的对象进行比较。然后,也许我需要删除来自父级的一些对象,和/或用子级中的一些新闻替换来自父级的一些对象,和/或将子级中的一些新对象插入父级

调用for (MyEntity *entity in self.entities) { // this is main thread [self.privateContext performBlockAndWait: ^{ [self.privateContext objectWithID:entity.objectID]; [self.tempEntities addObject:entity]; }]; } 会将父上下文中的所有对象替换为子对象中的对象,还是如何处理合并?

再次感谢

1 个答案:

答案 0 :(得分:4)

您仍然在后台线程中访问主线程对象,这是不允许的。这可以工作(如果它不触发自动提取),但在进入后台线程之前获取对象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...
    }
 }];

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

有两种途径:听NSManagedObjectContextObjectsDidChangeNotification更复杂,风险更大。在通知处理程序中,您可以更新阵列和表视图。尽管如此,这仍然存在风险,因为没有内存或性能优化等。

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