你好(实际问题在底部)。
在iOS 5中,在CoreData中引入了父子管理对象上下文。
我有一个标准的NSFetchedResultsController和UITableVeiwController协同工作,从商店中获取主列表。获取的结果控制器的托管对象上下文是具有父上下文的子项:
// 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];
}
问题:
我的理解是,在父子环境中,父上下文将从其子级获取保存通知,然后通知其所有子级。所以在我的例子中,构建上下文应该触发父上下文来告诉获取的结果控制器合并更改。
这种情况不会发生在我身上,记录已成功创建,但获取的结果控制器并没有将它们捡起来。我知道以前必须从保存通知中实现自己的合并(如CoreDataBooks中所示)。但我认为孩子 - 父母的背景解决了这个问题。我试图保存孩子,然后是父母,但似乎没有什么区别。有人可以向我解释一下吗? (注意:这些不是单独/后台线程的上下文)
非常感谢
答案 0 :(得分:14)
根据WWDC 2011关于“核心数据有什么新内容”的演示,它说你应该这样保存:
[child save:&error];
[parent performBlock:^{
[parent save:&parentError];
}];
根据我的理解,这会导致父级从子上下文接收和合并更改。需要注意的一点是,必须使用相同的并发类型创建父级和所有子级。
- 编辑删除了错误的假设,即父级将更改推送给子级,但不是。