【问题标题】:Core Data undo coalescing for an action spanning multiple run loop cycles跨多个运行循环周期的操作的核心数据撤消合并
【发布时间】:2011-03-19 01:21:53
【问题描述】:

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

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

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

【问题讨论】:

    标签: core-data undo nsundomanager


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 事实证明,更简洁的方法并不适合我的应用程序——系统地引入一个单独的(可独立调整的)视图树与我的模型对象并行会引入太多的复杂性。我最终使用了这个更简单的解决方案。
    【解决方案2】:

    我认为设置撤消管理器setGroupsByEvent: 可以满足您的需求。

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

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

    【讨论】:

    • 可悲的是 setGroupsByEvent: 在这里没有帮助。拖动跨越多个事件,所以除非我误解了一些基本的东西,否则没有办法明确地将我的更改与beginUndoGrouping/endUndoGrouping 分组 - 并且setGroupsByEvent 在已经有一个开放组时变成了无操作。在拖动手势结束之前不更改模型可能是最好的方法。问题是我没有地方存储瞬态位置——我直接从模型中进行渲染,没有单独的视图对象。但也许这只是意味着现在是时候添加它们了!
    • IIRC,将groupsByEvent 设置为NO,您将获得一个超越运行循环的长撤消组。
    • Sigh 不,将groupsByEvent 设置为NO 只会禁用隐式分组,因此您需要始终开始和结束自己的组。是的,您自己创建的组显然可以超越单个运行循环迭代。那不是问题。问题是在每次运行循环迭代结束时自动调用performPendingChanges 引起的内存使用和性能问题。您建议的更简洁的解决方案恰好是一个很好的解决方法:如果模型仅在手势结束时更改,performPendingChanges 不会在每次运行循环迭代中注册新的撤消操作。
    • 好吧,我有一阵子没弄了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-07
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多