Objective c 如何通过父MOC将一个子托管对象上下文中的更改合并到另一个子托管对象上下文中?
您好(下面是实际问题) 在iOS 5中,CoreData中引入了父子托管对象上下文 我有一个标准的NSFetchedResultsController和UITableVeiwController一起工作,从存储中获取主列表。获取的结果控制器的托管对象上下文是具有父上下文的子对象:Objective c 如何通过父MOC将一个子托管对象上下文中的更改合并到另一个子托管对象上下文中?,objective-c,core-data,ios5,Objective C,Core Data,Ios5,您好(下面是实际问题) 在iOS 5中,CoreData中引入了父子托管对象上下文 我有一个标准的NSFetchedResultsController和UITableVeiwController一起工作,从存储中获取主列表。获取的结果控制器的托管对象上下文是具有父上下文的子对象: // AppDelegate.m - (NSManagedObjectContext *)managedObjectContext { if (__managedObjectContext != nil)
// AppDelegate.m
- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext != nil)
{
return __managedObjectContext;
}
__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
// primary managed object context has NSPrivateQueueConcurrencyType
[__managedObjectContext setParentContext:[self primaryObjectContext]];
return __managedObjectContext;
}
表视图控制器提供模式视图控制器以添加新记录,但使用单独的托管对象上下文(此上下文是父上下文的另一个子上下文)来添加新记录。此上下文保存在表视图控制器中的委托回调中:
- (void)addGame
{
// New child context
[self setBuildManagedObectContext:[[NSManagedObjectContext alloc] init]];
[[self buildManagedObectContext] setParentContext:[[[self team] managedObjectContext] parentContext]];
Team *buildTeam = (Team *)[[self buildManagedObectContext] objectWithID:[[self team] objectID]];
Game *buildGame = [NSEntityDescription insertNewObjectForEntityForName:@"Game"
inManagedObjectContext:[self buildManagedObectContext]];
[buildGame setTeam:buildTeam];
BuildViewController *buildVC = [[BuildViewController alloc] initWithGame:buildGame delegate:self];
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:buildVC];
[[self navigationController] presentViewController:navCon animated:YES completion:nil];
}
#pragma mark - Build view controller delegate
- (void)buildViewController:(BuildViewController *)controller didFinishWithSave:(BOOL)save
{
if (save)
{
NSError *error = nil;
if (![[self buildManagedObectContext] save:&error])
{
NSLog(@"Error saving new game");
abort();
}
}
[self setBuildManagedObectContext:nil];
[[self navigationController] dismissViewControllerAnimated:YES completion:nil];
}
问题:
我的理解是,对于父子上下文,父上下文将从其子上下文获得save通知,然后通知其所有子上下文。因此,在我的示例中,构建上下文应该触发父上下文,告诉获取的结果控制器合并更改
我没有遇到这种情况,记录已成功创建,但获取的结果控制器没有拾取记录。我知道以前的情况是,您必须从保存通知中实现自己的合并(如中所示)。但我认为孩子的父母环境解决了这个问题。我试着救了孩子,然后又救了父母,但似乎没有什么不同。有人能给我解释一下吗?(注意:这些不是单独/后台线程上的上下文)
非常感谢根据WWDC 2011年关于“核心数据的新功能”的演示,它说您应该这样保存:
[child save:&error];
[parent performBlock:^{
[parent save:&parentError];
}];
据我所知,这会导致父对象接收并合并来自子上下文的更改。需要注意的一点是,必须使用相同的并发类型创建父级和所有子级
--编辑删除了错误的假设,即父级将更改推送到子级,而不是。“需要注意的是,父级和所有子级必须使用相同的并发类型创建。”嗯。。。如果要在后台提取更新MOC的数据并支持主线程中的UI,它们将不是相同的并发类型???@user786383使用NSMainQueueConcurrencyType作为并发类型不会对UI线程产生不利影响或阻止UI线程。如果使用MOC执行获取以更新UI元素(例如,通过NSFetchedResultsController填充UITableView),则最好使用该并发类型。父上下文不会“推送更改”到现有子上下文。因此,如果在子上下文1上进行更改,保存子上下文1并保存父上下文,则子上下文2中该实体的活动实例将不会有该更改。您必须在子上下文2上调用
reset
,然后重新获取对象以查看在子上下文1中所做的更改。如果子上下文2没有实体的任何缓存实例,则这不是问题,但重要的是要理解,这是因为上下文在获取时从持久性存储中提取,而不是因为父上下文推送到它的子上下文。@ChristopherPickslay你是个漂亮的人。@afrederick我认为你在这一点上错了。子MOC可以具有与父MOC不同的并发类型: