我的iPad应用程序(一个OpenGL绘图应用程序)中有一个有点复杂的数据模型,我正在努力实现撤消/重做功能。我喜欢Core Data将免费撤消数据模型更改这一事实,但我不知道内置功能是否足以让我满意。
我已经看到很多在绘图应用程序中实现撤消/重做的示例,但是它们通常会执行以下操作:
undo
。这非常低效 - 在我的应用程序中,我需要能够根据正在“撤消”的特定对象执行撤消操作,这通常意味着只刷新画布的一部分。
所以我的问题是:我可以注册自己的撤消操作并将其与内置的撤消操作结合使用吗?例如,假设我在用户绘制一条线时执行以下操作:
- (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
滚动我自己,包括自己删除和编辑数据模型?除非我能说出内置的撤消/重做实际上是什么撤消,否则看起来这可能会变得非常麻烦和复杂......
编辑:我怀疑(如果上面的想法是可行的)我需要将其包装到撤消组中,以便我的注册撤消操作将与数据模型更改分组? / p>
另一个编辑:另外,我可以保证撤消操作的执行顺序吗?换句话说,如果在保存核心数据更改并注册撤消操作后调用undo
,是否可以确保在调用撤消操作之前将恢复已删除的实体?
答案 0 :(得分:2)
您是否知道是否可以识别从撤消中更改了哪些数据?
为什么不查看NSManagedObjectContext
(Apple Docs)
使用密钥NSInsertedObjectsKey
,NSUpdatedObjectsKey
和NSDeletedObjectsKey
详细查看通知的 userInfo 。
另外,我可以保证执行撤消操作的顺序吗?
好吧,撤消通过堆栈(后进先出)工作,所以你“应该”能够追踪你的步骤。显然,如果你想要正确展开你的东西,你必须在你注册你的地址的顺序非常具体。几行代码可以帮助我跟踪撤消堆栈,只是为了看看神秘面纱背后的东西:
id undoStack, redoStack;
object_getInstanceVariable(undoManager, "_undoStack", &undoStack);
object_getInstanceVariable(undoManager, "_redoStack", &redoStack);
NSLog(@"%@", [undoStack description]);
NSLog(@"%@", [redoStack description]);
答案 1 :(得分:0)
使用flyweight
结构。 It is generally used用于撤消/重做操作。你问的问题要求你自己做。
Flyweights可以根据需要存储尽可能多的数据,您可以随时将其从撤消序列中删除。例如,您的flyweights可以在每次编辑之前存储像素数据。这将占用大量内存,但您可以轻松撤消某些内容,而无需重新绘制整个场景。