跳转到内容

WebObjects/EOF/使用 EOF/撤销和重做

来自维基教科书,开放世界中的开放书籍

有人能告诉我 NSUndoManager 是否只与 EOF 一起使用,或者我是否可以在自己的应用程序中使用它(不使用 EOF) ?

撤销/重做可以与任何类型的应用程序一起使用(这就是您在 Foundation 中找到 NSUndoManager 的原因,而不是像 WOF 或 EOF 这样的更高策略级别框架)。当然,WOF 和 EOF 预先配置为使用 NSUndoManager,WOF 会在请求/响应循环周围自动创建撤销组(尽管如果您愿意,您可以创建子组以获得更细粒度的控制),而 EOF 的 EOEditingContext 预先连接以使用 NSUndoManager。

我不知道为什么人们不更多地使用它……我想这是惯性。如果您只在应用程序中使用一个 EOEditingContext 并且用户单击撤销,他们可能会对发生的事情感到困惑,除非您小心地警告用户他们在非活动页面中发出撤销请求(他们回溯)。如果用户回溯到旧页面并在那里按下撤销,则撤消的更改可能发生在最近的时间。对用户来说,似乎没有任何变化,但实际上已经发生了变化,但他们只是不知道是什么。另一个原因是,EC 更改通常伴随着 UI 状态更改,而撤销仅适用于 EC 中的更改。例如,您可能希望撤消订单的运送设置。仅仅调用撤销就会做到这一点,但它不会改变您在结账过程中的步骤的表示状态。

另一个问题是用户和开发人员没有意识到,撤销某些操作可能无法在没有额外干预的情况下恢复……就像对存储在数据库中的计数器的更新。或者它们可能是可逆的,但用户或开发人员没有意识到需要再次调用 saveChanges 来将 EC 中撤消的对象图推回到 DB。

人们有时不使用撤销,而是使用基于任务的编辑上下文,并结合使用 revert() 和/或 EC 替换……也就是说,您将一个 EC 专用于结帐流程,另一个 EC 专用于在商店中浏览的数据,另一个 EC 专用于编辑帐户信息。如果用户不想提交更改,您可以对 EC 调用 revert,丢弃自上次提交以来的所有更改。但是,一旦您将 EC 分解成这样的任务,您和您的用户可能对撤销/重做会发生什么有更清晰的认识。例如,在“客户编辑”中的撤销不会撤消您在“产品管理”编辑 EC 中的最后一次更改。

在 Web 应用程序中撤销/重做的一种可取方法是使用 NSUndoManager 通知消息(当创建撤销组时会调用这些消息)。这可能允许对象图更改(EOEditingContext 和 NSUndoManager 管理的状态)与您特定于应用程序的会话状态(您直接管理)保持同步。它还可以让您有能力将页面与撤销发生的更改相关联。例如……想象一下用户编辑了一些客户信息。用户转到另一个客户或其他类型的信息并在那里进行了两次编辑。用户点击了几次。现在假设任何调用撤销的操作都会将撤销组与在创建撤销组时存储有关该组的状态相关联?您可能能够恢复有关 PK 和与进行更改的页面关联的实体名称的信息;这反过来将允许您将用户带回一个适当的编辑器页面,该页面预先填充了主要受撤销影响的 EOEnterpriseObject 对象。我从未尝试过这样的事情,但它可能是可能的。

如果用户通常只查看一些区域的所有可能更改的数据,那么所有这些都不会真正那么有趣或必要。撤销/重做影响将立即显现出来。如果 EC 中存在未提交的更改,您可能仍然希望向用户发出警示,以便他们知道如果需要,尝试保存其更改。

如果用户无法轻松地看到撤销和重做的影响,您可能使用另一种方法,包括汇总 EC 中更新的、插入的和已删除列表中的 EO 的当前内容。这可能是在屏幕底部的小区域,其中列出了这些数组的计数,或者列出了未提交的 EO 的实体名称及其计数。您甚至可以使用 changes-from-snapshot API 来显示任何未提交更新中的实际更改。当用户进行撤销时,您可能会将用户带到一个页面,该页面会以所有荣耀展开这些更改信息。用户可以在这样的页面上来回切换撤销/重做,并清楚地了解所讨论的撤销的范围。如果一切看起来都正常,那么他们就可以对 EC 调用 saveChanges。

PS:如果您不经常使用撤销/重做,我想重点介绍一些重要的文档……

EOEditingContext 的撤销支持是任意深度的;您可以反复撤销一个对象,直到将其恢复到第一次创建或提取到其编辑上下文时的状态。即使在保存后,您也可以撤销更改。为了支持此功能,NSUndoManager 可以在内存中保留大量数据。

例如,每当从关系中删除一个对象时,相应的编辑上下文都会创建一个修改后的源对象的快照。该快照包含对已删除对象的引用,由编辑上下文和撤销管理器引用。当更改被保存时,编辑上下文会释放对快照的引用,但撤销管理器不会。它会继续持有快照,以便在请求时撤消删除。

如果应用程序的典型使用模式会产生大量的更改处理,您可能希望限制撤销功能以控制其内存使用。例如,您可以在其编辑上下文保存时清除撤销管理器。为此,只需向撤销管理器发送 removeAllActions 消息(或使用编辑上下文作为参数的 removeAllActionsWithTarget 消息)。如果您的应用程序根本不需要撤销,您可以通过使用 setUndoManager 将编辑上下文的撤销管理器设置为 null 来避免任何撤销开销。

更多信息

[编辑 | 编辑源代码]

如果您正在使用撤销/重做,那么阅读 内存管理 部分非常重要。

华夏公益教科书