跳轉到內容

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 來避免任何撤銷開銷。

更多資訊

[編輯 | 編輯原始碼]

如果您正在使用撤銷/重做,那麼閱讀 記憶體管理 部分非常重要。

華夏公益教科書