2

我的 iPad 应用程序(一个 OpenGL 绘图应用程序)中有一个有点复杂的数据模型,我正在努力实现撤消/重做功能。我喜欢 Core Data 将免费撤消数据模型更改的事实,但我不知道内置功能是否足以满足我的需求。

我已经看到很多在绘图应用程序中实现撤消/重做的示例,但是它们通常执行以下操作:

  1. 将托管对象上下文告知undo.
  2. 从更改的数据模型中重绘页面上的所有内容。

这是非常低效的——在我的应用程序中,我需要能够根据正在“撤消”的特定对象执行撤消操作,这通常意味着只刷新画布的一部分。

所以我的问题是:我可以注册自己的撤消操作并将其与内置撤消一起使用吗?例如,假设我在用户画一条线时执行以下操作:

- (void)drawLineFromPoint:(CGPoint)startPoint toPoint:(CGPoint)endPoint
{
    // Register the undo operation.
    [[[managedObjectContext undoManager] prepareWithInvocationTarget:self] 
                                               removeObjectWithIndex:nextObjectIndex];

    // Draw the line object.  
    [self drawLineObjectWithIndex:nextObjectIndex fromPoint:startPoint toPoint:endPoint];

    // Save the new object to the data model.
    [MyCoreDataHelper saveLineObjectWithIndex:nextObjectIndex fromPoint:startPoint toPoint:endPoint];

    nextObjectIndex++;
}

当我要撤消此操作时,会触发调用适当更改模型吗?或者这种情况是否需要我放弃内置的托管对象上下文撤消系统并使用我自己的NSUndoManager,包括自己删除和编辑数据模型?除非我能分辨出内置的撤消/重做实际上是在撤消什么,否则看起来这可能会变得非常混乱和复杂......

编辑:我怀疑(如果上面的想法可行)我需要将它包装到一个撤消组中,以便我注册的撤消操作将与数据模型更改分组?

另一个编辑:另外,我可以保证执行撤消操作的顺序吗?换句话说,如果我undo在保存核心数据更改并注册我的撤消操作之后调用,我是否可以确保在调用我的撤消操作之前恢复已删除的实体?

4

2 回答 2

2

您是否知道是否可以识别撤消更改了哪些数据?

为什么不查看NSManagedObjectContext (Apple Docs)的通知

具体查看通知的userInfoNSInsertedObjectsKey,包括NSUpdatedObjectsKey、 和NSDeletedObjectsKey

另外,我可以保证撤消操作的执行顺序吗?

好吧,撤消通过堆栈(后进先出)工作,因此您“应该”能够跟踪您的步骤。显然,如果您希望事情正确展开,您必须按照注册撤消的顺序非常具体。几行代码可以帮助我跟踪撤消堆栈,以了解神秘面纱背后的内容:

id undoStack, redoStack;
object_getInstanceVariable(undoManager, "_undoStack", &undoStack);
object_getInstanceVariable(undoManager, "_redoStack", &redoStack);
NSLog(@"%@", [undoStack description]);
NSLog(@"%@", [redoStack description]);

(以上代码为本站的道具)

于 2012-01-26T01:47:00.770 回答
0

使用flyweight结构。它通常用于撤消/重做操作。您所要求的要求您自己执行此操作。

享元可以存储尽可能多的数据,并且您可以随时将它们从撤消序列中删除。例如,您的享元可以在每次编辑之前存储像素数据。这将占用大量内存,但您可以轻松撤消某些操作而无需重绘整个场景。

于 2012-01-27T04:13:28.117 回答