我有一个iPad应用程序,我正在使用带有核心数据的NSUndoManager。事情通常很有效,除了当我多次撤消/重做时有一个半可重复的错误。我只在主线程上工作(至少,我已禁用MagicalRecords在辅助线程上使用NSManagedObject。如果我尝试撤消/重做NSManagedObject到上下文的插入,则会出现问题。
所以我有这样的事情:
if (!self.undoManager.isUndoing && !self.undoManager.isRedoing)
{
[self.undoManager undo];
}
else
{
NSLog(@"gotcha!");
}
经过几次,我得到以下异常。它发生在辅助线程上,这让我觉得Core Data正在后台做一些事情。
CoreData: error: Serious application error. Exception was caught during Core Data
change processing. This is usually a bug within an observer of
NSManagedObjectContextObjectsDidChangeNotification. _registerUndoObject:: NSUndoManager
0xcea2d60 is in invalid state, must begin a group before registering undo
with userInfo (null) 2012-07-25 15:42:26.850 TT[3972:3c07] *** Terminating app due to
uncaught exception 'NSInternalInconsistencyException', reason: '_registerUndoObject::
NSUndoManager 0xcea2d60 is in invalid state, must begin a group before registering undo
有时我也会获得EXEC_BAD_ACCESS,有时候只是上面的例外。
知道可能导致这种情况的原因吗?
编辑:Mundi的澄清情况(见评论)
答案 0 :(得分:0)
撤消托管对象插入的标准方法是
[self.managedObjectContext deleteObject:theManagedObject];
// If you have saved already, you would need to save again.
无需使用撤消机制。像这样,您的代码变为
答案 1 :(得分:0)
这是阻止我所有崩溃的解决方案: 显然,Magical Records默认使用privateQueue并发,如果你的代码不是那么线程安全的话,我想事情就不行了。我所做的是将NSPrivateQueueConcurrencyType更改为NSMainQueueConcurrencyType以获取以下方法:
+ (NSManagedObjectContext *) MR_contextWithoutParent;
{
NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
return context;
}
我还发现了另一个在这里工作的细节: Core Data deleteObject: sets attributes to nil
我需要做的是在添加/删除托管对象之前保存托管对象上下文。有点奇怪和低效,但节省了很多麻烦。