自动保存不适用于 UIManagedDocument 上的 NSUndoManager
Posted
技术标签:
【中文标题】自动保存不适用于 UIManagedDocument 上的 NSUndoManager【英文标题】:Auto-save not working with NSUndoManager on UIManagedDocument 【发布时间】: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
【参考方案1】:
我不确定它是否正确,但 *** 上的其他答案提到 NSUndoManager 在上下文保存时清除撤消堆栈。这意味着使用具有自动保存功能的撤消管理器最多可以使用几秒钟(无论自动保存间隔是多少)。那里可能有联系,我正在尝试了解更多...
【讨论】:
有趣 - 它与我看到的其他行为相匹配,我从哪里开始撤消组,进行一些更改,然后进行撤消。有时自动保存发生在开始和撤消之间,因此撤消不会撤消任何操作。这比没用!任何这种行为是设计使然的具体证据都会有所帮助。我在 NSUndoManager 清除撤消堆栈或 Apple doco 中的任何内容上找不到其他答案。 我有更多信息。托管文档仅自动保存其自己的两个上下文,因此您必须创建自己的子上下文以防止在不好的时候自动保存。然后手动保存上下文。也就是说,我认为撤消管理器不应该为您的用户管理撤消堆栈,而只是为您的核心数据操作。 对我来说,结果是如果你要使用 NSUndoManager,它必须在子上下文中。因此,如果要求只是支持保存/取消而不是真正的撤消/重做,那么使用 NSUndoManager 没有任何价值,因为它是通过保存或丢弃子上下文来完成的。我会将您的答案标记为正确。以上是关于自动保存不适用于 UIManagedDocument 上的 NSUndoManager的主要内容,如果未能解决你的问题,请参考以下文章