嗨:)我有一个像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)中,我列出了这个集合的一些项目,我可以与之交互(例如设置开关)。
我还有一个editObjectContext:
// 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];
}
但是在我选择了托管视图中的项目并单击了save(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
}
在一个只有1个视图的Verison中,它有效,我没有太多变化...:/所以我不明白为什么MOC表现得像它一样。 “manageItems”部分几乎相同,它只是新版本中更深层次(在DetailsView而不是控制器中)......
如果有人可以告诉我我可以尝试什么(当管理和普通之间的切换不是解决方案时总是保存到服务器,因为服务器响应的延迟对刷新来说很高,所以我有更少的翻转视图。使用self.tableView / detailView / self.containerView刷新刷新视图也会产生相同的结果:/)。
和第二个问题:发送到服务器之后我无法调用“editingObjectContext save:”方法,因为它抛出错误而根本不保存到本地数据库。
handleChangeResponse出错: 错误域= NSCocoaErrorDomain代码= 133020“操作无法完成。(可可错误133020)。”UserInfo = 0x4d8bb90 {conflictList =( “NSMergeConflict(0x5a2fac0)for NSManagedObject(0x5a46a80),objectID为'0x5a46420',oldVersion = 7,newVersion = 8,旧对象快照= {\ n iconName = noicon; \ n [...]; \ n}和新的缓存行= {\ n iconName = noicon; \ n [...] \ n}“ )}
如果您有疑问或需要更多代码(即旧版本),那么请问;)
感谢期待:)
答案 0 :(得分:6)
好像我有解决方案!从IOS 5.0开始,NSManagedObjectContext有一个新方法:
[managedObjectContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
在http://pauloliveira.net/tech/core-data-merging-conflicts上找到 将此属性设置为顶级MOC(在我的案例中为appDelegate),而不是其他地方!清除我的合并问题;)
答案 1 :(得分:0)
我找到了它无效的原因...忘记了我上面写的所有内容...问题出在fetchrequest中 - 具体来说:在谓词中......在我使用的早期版本中
[NSComparisonPredicate predicateWithLeftExpression: ...]
在我使用的实际版本中
NSString * predicateFormat = [NSString stringWithFormat: ...];
NSPredicate* predicate = [NSPredicate predicateWithFormat:predicateFormat];
因为我必须扩展选项的数量并且还编辑了请求本身,因为它在谓词中产生了问题(比较一个完整的对象(MOC类,从数据库中提取)与一个实体没有用,所以我在DetailsViewController中管理了解决方法,并且没有在这个地方回滚我的更新:/)。
从来没有想过要在这个问题上浪费那么多时间&gt;。但没关系,只要它已经解决:D
我将检查第二个问题(保存问题)是否仍然存在。如果没有,我会更新我的帖子,否则这个主题没有关闭:/
答案 2 :(得分:0)
这可能是由于使用对象的manageobject上下文所导致的。在您退出或退回时删除所有NSManagebobject。说结束使用应用程序。看起来像这样......
[NSManagebobjectcontext setManagedObjectsDictionary:[NSMutableDictionary dictionary]];