2013-03-05 80 views
3

分辨率

NSUndoManager只能在孩子NSManagedObjectContext(核心數據使用時)可以使用不工作。這是因爲UIManagedDocument可能會在任何時間點自動保存,之後undo將不起作用。因此,使用NSUndoManager來實現保存/取消功能毫無意義,因爲子上下文會給您相同的結果。自動保存NSUndoManager上UIManagedDocument

真的有點難過,因爲NSUndoManager比兒童環境更容易實現(對於後者我必須調用existingObjectWithID將對象從父對象複製到兒童 - 痛苦)。就個人而言,我會認爲文檔不應該自動保存,如果groupingLevel != 0。 Rant完成了。

原始的問題

我有使用核心數據爲UIManagedDocument該負載數據的表視圖控制器。它延伸到視圖控制器來編輯表中的每一行。在該視圖控制器中,我已取消並保存按鈕。我正在通過我的NSManaged對象(下面的self.list)上的類別使用NSUndoManager來實施取消功能。

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self.list beginEdit]; 
} 

- (IBAction)cancel:(id)sender 
{ 
    [self.list cancelEdit]; 
    [self close]; 
} 

- (IBAction)save:(id)sender 
{ 
    [self.list endEdit]; 
    [self close]; 
} 

類別實現beginEditendEditcancelEdit其目的是處理NSUndoManager東西。在下面的代碼中,useUndo是一個常量,我將其設置爲NO或YES以查看使用NSUndoManager的影響。

- (void)beginEdit 
{ 
    if (useUndo) 
    { 
     NSUndoManager *undoManager = [[NSUndoManager alloc] init]; 
     self.managedObjectContext.undoManager = undoManager; 
     [undoManager beginUndoGrouping]; 
    } 
} 

- (void)endEdit 
{ 
    [self.managedObjectContext save:nil]; 
    if (useUndo) 
    { 
     NSUndoManager *undoManager = self.managedObjectContext.undoManager; 
     [undoManager endUndoGrouping]; 
     self.managedObjectContext.undoManager = nil; 
    } 
} 

- (void)cancelEdit 
{ 
    if (useUndo) 
    { 
     NSUndoManager *undoManager = self.managedObjectContext.undoManager; 
     [undoManager endUndoGrouping]; 
     [undoManager undo]; 
    } 
} 

我可以看到核心數據調試消息顯示它被提交的修改,如果我保存對象,然後單擊當Home鍵useUndo = NO。但是,使用useUndo = YES時,單擊主頁按鈕時它不會自動保存。我等了幾分鐘,但仍然沒有自動保存。有什麼辦法可以強制自動保存嗎?

任何人都可以解釋爲什麼使用undoManager導致這種行爲改變?

我懷疑我是以錯誤的方式去做,或者在代碼中遇到一些簡單的問題。任何幫助,將不勝感激。

+0

首先,在使用'UIManagedDocument'時,絕不要調用'[self.managedObjectContext save:nil]'(如果它不是childContext) 。您應該始終在您的UIManagedDocument對象上調用'updateChangeCount:'。請參閱:[使用託管文檔的託管對象上下文](http://developer.apple.com/library/ios/#documentation/uikit/reference/UIManagedDocument_Class/Reference/Reference.html) – 2013-04-19 09:42:40

回答

1

我不確定它是否正確,但stackoverflow上的其他答案提到NSUndoManager在上下文保存時清除了撤消堆棧。這意味着使用具有自動保存的撤銷管理器最多可以在幾秒鐘內有用(無論自動保存間隔是多少)。可能有一個連接,我試圖找出更多...

+0

有趣的是,它與我的其他行爲相匹配看到我開始撤消組的位置,進行一些更改,然後進行撤消。有時自動保存會在開始和撤消之間發生,因此撤消任何操作都不會撤消。這是沒用的!任何具體的證據表明這種行爲是通過設計將是有幫助的。我無法在NSUndoManager上清除撤消堆棧或Apple doco中的任何其他答案。 – Michael 2013-08-28 02:24:10

+0

我有一些更多的信息。託管文檔僅自動保存其自己的兩個上下文,因此您必須創建自己的子上下文以防止在不良時間自動保存。然後手動保存上下文。也就是說,我認爲撤銷管理器不應該爲您的用戶管理撤消堆棧,只能用於您的核心數據操作。 – Andreas 2013-08-30 12:37:01

+0

對我來說,結果是,如果你要使用NSUndoManager,它必須在一個子上下文中。因此,如果需求只是支持保存/取消而不是真正的撤銷/重做,則使用NSUndoManager沒有價值,因爲它通過保存或丟棄子上下文來完成。我會標記你的答案是正確的。 – Michael 2013-09-04 01:50:43