разрешение
NSUndoManager
должен использоваться только в дочернем элементе NSManagedObjectContext
(при использовании с Core Data). Это связано с тем, что UIManagedDocument
может автоматически сохраняться в любой момент времени, после чего undo
не будет иметь никакого эффекта. Поэтому нет смысла использовать NSUndoManager
только для достижения функциональности сохранения/отмены, поскольку дочерний контекст даст вам тот же результат.
На самом деле немного грустно, потому что NSUndoManager
намного проще реализовать, чем дочерний контекст (для последнего мне нужно вызвать existingObjectWithID
, чтобы скопировать объекты из родителя в дочерний - болезненно). Лично я бы подумал, что документ не должен автоматически сохраняться, если groupingLevel != 0
. Рэнт закончил.
Оригинальный вопрос
У меня есть контроллер табличного представления, который загружает данные с помощью Core Data в файл UIManagedDocument
. Он переходит к контроллеру представления для редактирования каждой строки в таблице. В этом контроллере представления у меня есть кнопки отмены и сохранения. Я реализую возможность отмены, используя NSUndoManager
через категорию моего объекта NSManaged
(self.list
ниже).
- (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];
}
Категория реализует beginEdit
, endEdit
и cancelEdit
, которые предназначены для обработки материала 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];
}
}
Я вижу отладочные сообщения Core Data, показывающие, что он фиксирует изменения, если я сохраняю объект и нажимаю кнопку «Домой», когда useUndo = NO
. Однако с useUndo = YES
он не сохраняется автоматически, когда я нажимаю кнопку «Домой». Я подождал пару минут, и он все еще не автосохраняется. Можно ли как-то принудительно выполнить автосохранение?
Кто-нибудь может объяснить, почему использование undoManager вызывает такое изменение поведения?
Я подозреваю, что либо я делаю это неправильно, либо у меня есть какая-то простая проблема в коде. Любая помощь будет оценена по достоинству.
[self.managedObjectContext save:nil]
(если это не childContext) при использованииUIManagedDocument
. Вы всегда должны вызыватьupdateChangeCount:
для своего объекта UIManagedDocument. См.: Использование контекста управляемого объекта управляемого документа - person Florian Mielke   schedule 19.04.2013