将 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
我想将属于 mainContext
的 NSMutableArray
(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 或其他数据结构。您可以免费获得许多强大的功能。
我在 class 中有一个 NSMutableArray
属性,其中我一直引用 NSManagedObjectContext
的一些托管 objects,我称之为 [=16] =] 并且关联到主队列。在同一个 class 中,我在私有队列中创建了一个 privateContext
并将其设置为 mainContext
.
我想将属于 mainContext
的 NSMutableArray
(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 或其他数据结构。您可以免费获得许多强大的功能。