1

我有一个基于核心数据的 UIKit 应用程序,它允许用户在屏幕上拖动对象。在拖动对象时,我会在每个touchesMoved:事件上更新其位置属性。为了支持一次性撤消拖动操作,我在拖动开始时启动了一个新的撤消组,并在用户抬起手指时结束该组。

为了节省内存并使撤消操作快速,我想合并属于拖动操作的撤消数据,但 Core Data 使这变得困难。问题是processPendingChanges在每个运行循环周期结束时调用它,它会强制 Core Data 为该迭代中发生的位置更改归档一个新的撤消记录。一个拖拽操作可以很容易地累积数百条这样的撤销记录,除了第一个之外,所有这些都是不必要的。

有没有办法让我继续使用 Core Data 神奇的内置撤消支持,但又不会在重复的撤消记录上浪费宝贵的内存?我喜欢我不需要关心在撤消/重做操作之间维护对象图的一致性,但无法正确处理这些连续的属性更新似乎是一个阻碍。

4

2 回答 2

3

我认为设置撤消管理器setGroupsByEvent:会做你想做的事。

设置一个布尔值,指定接收器是否在运行循环期间自动对撤消操作进行分组。如果是,则接收器在每次通过运行循环时创建撤消组;如果不是,则不是。

一个更简洁的解决方案可能是在拖动事件结束之前不将对象位置提交给数据模型。

于 2010-07-22T14:13:05.990 回答
0

一种解决方案是在第一个拖动事件后禁用所有撤消注册,并保持禁用状态直到整个手势完成。

如果您已groupsByEvent启用,则需要记住,撤消管理器会在注册关闭时忽略所有分组消息,包括在事件结束时自动结束隐式组的消息。因此,如果您打算在运行循环结束时关闭注册,则必须自己手动关闭隐式组:

[moc processPendingChanges];
while ([moc.undoManager groupingLevel])
    [moc.undoManager endUndoGrouping];
[moc.undoManager disableUndoRegistration];

拖动手势完成后,您可以使用以下代码重新启用撤消注册:

[moc processPendingChanges];
[moc.undoManager enableUndoRegistration];

该解决方案有效,但有点笨拙。TechZen 建议的更简洁:在拖动手势完成之前不要更新模型属性。

于 2010-07-23T22:14:30.757 回答