【发布时间】:2013-03-05 05:08:45
【问题描述】:
分辨率
NSUndoManager 只能用于子 NSManagedObjectContext(与 Core Data 一起使用时)。这是因为UIManagedDocument 可能会在任何时间点自动保存,之后undo 将不起作用。因此,使用NSUndoManager 来实现保存/取消功能是没有意义的,因为子上下文会为您提供相同的结果。
真的有点难过,因为NSUndoManager 比子上下文更容易实现(对于后者,我必须调用existingObjectWithID 将对象从父级复制到子级 - 很痛苦)。我个人认为如果groupingLevel != 0,文档不应该自动保存。吐槽完毕。
原始问题
我有一个表格视图控制器,它使用 Core Data 将数据加载到 UIManagedDocument 中。它使用视图控制器来编辑表格中的每一行。在那个视图控制器中,我有取消和保存按钮。我正在通过我的NSManaged 对象(下面的self.list)上的一个类别使用NSUndoManager 实现取消功能。
- (void)viewDidLoad
{
[super viewDidLoad];
[self.list beginEdit];
}
- (IBAction)cancel:(id)sender
{
[self.list cancelEdit];
[self close];
}
- (IBAction)save:(id)sender
{
[self.list endEdit];
[self close];
}
该类别实现了beginEdit、endEdit 和cancelEdit,它们旨在处理NSUndoManager 的东西。在下面的代码中,useUndo 是一个常量,我将其设置为 NO 或 YES 以查看使用 NSUndoManager 的影响。
- (void)beginEdit
{
if (useUndo)
{
NSUndoManager *undoManager = [[NSUndoManager alloc] init];
self.managedObjectContext.undoManager = undoManager;
[undoManager beginUndoGrouping];
}
}
- (void)endEdit
{
[self.managedObjectContext save:nil];
if (useUndo)
{
NSUndoManager *undoManager = self.managedObjectContext.undoManager;
[undoManager endUndoGrouping];
self.managedObjectContext.undoManager = nil;
}
}
- (void)cancelEdit
{
if (useUndo)
{
NSUndoManager *undoManager = self.managedObjectContext.undoManager;
[undoManager endUndoGrouping];
[undoManager undo];
}
}
如果我保存一个对象并在useUndo = NO 时单击主页按钮,我可以看到 Core Data 调试消息显示它正在提交更改。但是,对于useUndo = YES,当我单击主页按钮时它不会自动保存。我已经等了几分钟,它仍然没有自动保存。有什么方法可以强制自动保存吗?
谁能解释为什么使用 undoManager 会导致这种行为变化?
我怀疑我的处理方式有误,或者代码中有一些简单的问题。任何帮助将不胜感激。
【问题讨论】:
-
首先,在使用
UIManagedDocument时,永远不要调用[self.managedObjectContext save:nil](如果它不是childContext)。你应该总是在你的 UIManagedDocument 对象上调用updateChangeCount:。见:Using a Managed Document’s Managed Object Context
标签: ios nsundomanager uimanageddocument