跨多个运行循环周期的操作的核心数据撤消合并
我有一个基于 Core Data 的 UIKit 应用程序,允许用户在屏幕上拖动对象。拖动对象时,我会在每个 touchesMoved:
事件上更新其位置属性。为了支持一次性撤消拖动操作,我在拖动开始时启动一个新的撤消组,并在用户抬起手指时结束该组。
为了节省内存并使撤消操作更快,我想合并属于拖动操作的撤消数据,但 Core Data 使这变得很困难。问题在于 processPendingChanges 在每个运行循环周期结束时被调用,它强制 Core Data 为该迭代中发生的位置更改提交新的撤消记录。拖动操作可以轻松累积数百条此类撤消记录,除了第一个之外,所有这些记录都是不必要的。
有没有办法让我继续使用 Core Data 神奇的内置撤消支持,但又不会在此类重复的撤消记录上浪费宝贵的内存?我喜欢我不需要关心维护撤消/重做操作之间的对象图一致性,但无法正确处理这些连续的属性更新似乎是一个阻碍。
I have a Core Data based UIKit application that allows the user the drag objects around on the screen. While an object is being dragged, I update its position attribute on each touchesMoved:
event. To support undoing a drag operation in one go, I start a new undo group at the beginning of the drag, and end the group when the user lifts their finger.
To save memory and to make undo operations fast, I want to coalesce undo data belonging to the drag operation, but Core Data makes this difficult. The problem is that processPendingChanges
is called at the end of each run loop cycle, and it forces Core Data to file a new undo record for the position change that happened in that iteration. A drag operation can easily accumulate hundreds of such undo records, all of which but the first are unnecessary.
Is there a way for me to keep using Core Data's magical built-in undo support, but without wasting precious memory on such duplicate undo records? I love that I don't need to care about maintaining object graph consistency across undo/redo operations, but not being able to correctly handle these continuous attribute updates seems to be a showstopper.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为设置撤消管理器
setGroupsByEvent:
将执行您想要的操作。更简洁的解决方案可能是在拖动事件结束之前不将对象位置提交到数据模型。
I think setting the undo managers
setGroupsByEvent:
will do what you want.A cleaner solution might be to simply not commit the objects position to the data model until the end of the drag event.
一种解决方案是在第一个拖动事件之后禁用所有撤消注册,并保持禁用状态直到整个手势完成。
如果您启用了
groupsByEvent
,则需要记住,当注册关闭时,撤消管理器会忽略所有分组消息,包括在事件结束时自动结束隐式组的消息。因此,如果您打算在运行循环结束时关闭注册,则必须自己手动关闭隐式组:拖动手势完成后,您可以使用以下代码重新启用撤消注册:
此解决方案有效,但有点笨拙。 TechZen 建议的更简洁:在拖动手势完成之前不要更新模型属性。
One solution is to disable all undo registration after the very first drag event, and keep it disabled until the entire gesture is finished.
If you have
groupsByEvent
on, you'll need to keep in mind that the undo manager ignores all grouping messages while registration is off, including the one that ends the implicit group automatically at the end of the event. So if you plan to leave registration turned off at the end of the run loop, you'll have to manually close the implicit group yourself:Once the drag gesture is finished, you can re-enable undo registration with the following code:
This solution works, but it is a bit kludgy. The one suggested by TechZen is much cleaner: don't update model attributes until the drag gesture is done.