objective-c - NSUndoManager + endUndoGrouping 调用但没有匹配的开始

标签 objective-c cocoa core-data nsundomanager

我有一个基于 Cocoa 文档的应用程序,并且在使用 NSUndoManager 时遇到了一些问题,尽管我让 Core Data 处理了所有这些问题。

因此,每次创建新的持久文档时,我都会创建一个根上下文和一个子上下文。根上下文负责写入持久文档,子上下文是我通过创建/编辑/删除 NSManagedObjects 修改的上下文。我将根上下文设置为父上下文。我还将子上下文的撤消管理器设置为使用 NSPersistentDocument 创建的原始上下文。下面是一些代码,希望可以使其更清晰一些:

// create root context
NSManagedObjectContext *rootContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

// startContext is the context created with the document
[rootContext setPersistentStoreCoordinator:[startContext persistentStoreCoordinator]];
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

// set root as parent
[childContext setParentContext:rootContext];

// set undo
[childContext setUndoManager:[startContext undoManager]];

我这样做的原因是因为我遇到了如下所述的类似问题: Enable saving of document NSManagedObjectContext immediately?

所以我提出这个问题是因为这是我的应用程序中唯一触及 NSUndoManager 的代码。我正在通过简单地插入 NSManagedObjects 然后撤消插入来测试我的应用程序。有时,在两次撤消、或者五次、甚至十次撤消后,我会收到以下错误:

_endUndoGroupRemovingIfEmpty:: NSUndoManager 0x100159f30 is in invalid state,   endUndoGrouping called with no matching begin
2013-01-29 21:31:23.375 TestApplication[30125:303] (
0   CoreFoundation                      0x00007fff8a54f0a6 __exceptionPreprocess + 198
1   libobjc.A.dylib                     0x00007fff8215f3f0 objc_exception_throw + 43
2   CoreFoundation                      0x00007fff8a54ee7c +[NSException raise:format:] + 204
3   Foundation                          0x00007fff80ea021f -[NSUndoManager _endUndoGroupRemovingIfEmpty:] + 195
4   Foundation                          0x00007fff80ea0154 -[NSUndoManager endUndoGrouping] + 42
5   Foundation                          0x00007fff80ed79da +[NSUndoManager(NSPrivate) _endTopLevelGroupings] + 447
6   AppKit                              0x00007fff8253632d -[NSApplication run] + 687
7   AppKit                              0x00007fff824dacb6 NSApplicationMain + 869
8   TestApplication                     0x0000000100001512 main + 34
9   TestApplication                     0x00000001000014e4 start + 52

因此,如果我正确读取调试信息,那么我需要调用 [[context undoManager] beginUndoGrouping] 但问题是,我的程序中没有任何地方使用 `[ [上下文 undoManager] endUndoGrouping]'。有人以前经历过吗?

感谢任何帮助。

最佳答案

OSX 中的每个上下文默认创建一个 undoManager(iOS 中为 nil)。分组错误的原因是您的子上下文 undoManager 试图将更改嵌套在 rootContext 的 undoManager 中,而 rootContext 的 undoManager 嵌套在 startContext undoManager 中(与子上下文的 undoManager 相同)。

// create root context
NSManagedObjectContext *rootContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

// startContext is the context created with the document
[rootContext setPersistentStoreCoordinator:[startContext persistentStoreCoordinator]];
[rootContext setUndoManager:startContext.undoManager];
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

// set root as parent
[childContext setParentContext:rootContext];

关于objective-c - NSUndoManager + endUndoGrouping 调用但没有匹配的开始,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14595868/

相关文章:

cocoa - 如何判断系统偏好设置中的 Voice Over 是否已打开?

ios - 每次在嵌套条件 swift ios 中都会弹出 AlertController

ios - NSFetchedResultsController 对象在更新时从 UITableView 中删除

objective-c - 如何使用 NSKeyedArchiver 以 NSPropertyListXMLFormat_v1_0 格式将对象序列化为文件?

objective-c - 使类的实例在内存中保留更长时间(在 ARC 下)

objective-c - 如何通过 swift 使用 Chartboost 分析?

cocoa - 在 Cocoa/Carbon 下调试 NULL CGContext

cocoa - 用于 NSURL 书签的 Finder 风格 UI 丢失文件的数据解析?

ios - Core Data - 检测数据库存储是否已经创建

iphone - Objective-C : why release immediately after creating ui object