【发布时间】:2011-10-22 12:24:51
【问题描述】:
嗨 :) 我也有类似的问题,例如Working with the same NSManagedObjectContext in multiple tabs
背景:
我的 managedObjectContext(进一步的 MOC)在我的 appDelegate 类中初始化,并通过 myViewController.managedObjectContext = self.managedObjectContext; 或在带有 self.managedObjectContext = pContext; 的 init 方法中传递到多个选项卡
流程是:第一个视图是一个简单的集合列表。使用 NSFetchedResultsController (myViewController : UITableViewController<NSFetchedResultsControllerDelegate>) 获取集合。通过选择一个,您可以更深入地导航,但仍会通过此 MOC。
在下一个控制器(detailsViewController)中,我列出了这个集合中我可以与之交互的一些项目(例如设置开关)。
我还有一个editingObjectContext:
// DetailsViewController.m
NSManagedObjectContext* editingContext = [[NSManagedObjectContext alloc] init];
[editingContext setPersistentStoreCoordinator:[managedObjectContext persistentStoreCoordinator]];
self.editingObjectContext = editingContext;
现在我的问题:因为我的视图必须旋转,所以我使用以下技巧:
// DetailsViewController.m
DetailsView *localAct = [[DetailsView alloc] initWithManagedObjectContext:managedObjectContext ... ]
DetailsView *localSen = [[DetailsView alloc] initWithManagedObjectContext:managedObjectContext ... ]
UITableView *localContainerView = [[UITableView alloc] init];
self.containerView = localContainerView;
[localContainerView release];
//[...]
[containerView addSubview:actuatorView];
self.tableView = containerView;
此外,我还有一个按钮来管理这些项目(应显示哪些项目,哪些不显示)。这个按钮只是用一个新的 fetchResult 重新加载表。
// DetailsView.m
- (void) manageItems{
managing = !managing;
[viewController setIsManaging:managing]; // parent
self.fetchedResultsController = nil;
NSError *error = nil;
[[self fetchedResultsController] performFetch:&error];
[self reloadData];
[self updateBarButton];
}
将项目放入上下文的方法如下所示:
// DetailsViewController.m
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// init + create predicate
NSSet* set = [sen filteredSetUsingPredicate:predicate];
if( [set count] > 0 )
{
for( Act* act in set )
{
[editingObjectContext deleteObject:act];
}
}
else
{
Act* act = [NSEntityDescription insertNewObjectForEntityForName:@"Act" inManagedObjectContext:editingObjectContext];
// do things
}
NSError *error = nil;
[[detailView fetchedResultsController] performFetch:&error];
[self.containerView reloadData];
[detailView reloadData];
}
但是在我在托管视图中选择项目并单击保存 (manageItems) 后,视图不会显示它们:/ 我必须切换选项卡或在其他控制器(父级或更深)中导航以实现它. 我的 ViewWillAppear 方法:
// DetailsViewController.m
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
DetailsView *detailView = se ? senView : actView;
// [do uninteresting stuff]
[detailView.fetchedResultsController performFetch:nil];
[self.tableView reloadData];
// [do uninteresting stuff]
}
和 viewWillDisapper 调用
- (void)saveChanges
{
if( ![editingObjectContext hasChanges] )
return;
// send save-command to server
}
在一个较早的 Verison 中,它只有 1 个视图,但我并没有太大变化……:/ 所以我不明白 MOC 为什么会这样。 “manageItems”部分几乎相等,只是在新版本中更深一层(在 DetailsView 而不是控制器中)...
如果有人能告诉我我可以尝试什么(在管理和正常之间切换时始终保存到服务器不是解决方案,因为服务器响应的延迟对于刷新来说太高了,所以我有更少的翻转视图。同样使用 self.tableView / detailView / self.containerView refresh 刷新视图会带来相同的结果:/)。
第二个问题:发送到服务器后我无法调用“editingObjectContext save:”方法,因为它会抛出错误并且根本不保存到本地数据库。
handleChangeResponse 中的错误: 错误域=NSCocoaErrorDomain 代码=133020“操作无法完成。(Cocoa 错误 133020。)”UserInfo=0x4d8bb90 {conflictList=( “NSManagedObject (0x5a46a80) 的 NSMergeConflict (0x5a2fac0),objectID 为‘0x5a46420’,oldVersion = 7 和 newVersion = 8,旧对象快照 = {\n iconName = noicon;\n [...];\n} 和新的缓存行= {\n iconName = noicon;\n [...] \n}" )}
如果您有疑问或需要更多代码(即旧版本),请询问;)
感谢期待:)
【问题讨论】:
-
好的,我找到了一个可以使用翻转视图的版本...已经将代码复制到新版本中,但仍然是同样的问题...:/
- (void)manageItems /* DetailsViewController */ { DetailsView *detailView = isSen? senView : actView; [detailView manageItems]; }---- (void)manageItems //DetailsView { managing = !managing; [viewController setIsManaging:managing]; /* parent */ self.fetchedResultsController = nil; NSError *error = nil; [[self fetchedResultsController] performFetch:&error]; [viewController.containerView reloadData]; [self updateBarButton]; }
标签: iphone objective-c merge conflict nsmanagedobjectcontext