NSUndoManager с основными данными – повтор не работает
-
19-09-2019 - |
Вопрос
У меня есть приложение на основе документов Core Data, которое поддерживает отмену/повтор действия через встроенный NSUndoManager, связанный с NSManagedObjectContext.У меня настроено несколько действий, которые выполняют множество задач в Core Data, и я объединяю все эти задачи в группу отмены с помощью beginUndoGrouping
/endUndoGrouping
, и обрабатываются NSUndoManager.
Отмена работает нормально.Я могу выполнить несколько последовательных действий, каждое из которых затем последовательно отменить, и состояние моего приложения будет поддерживаться правильно.Однако пункт меню «Повторить» никогда не активируется.Это означает, что NSUndoManager сообщает меню, что нет элементов для повторного выполнения.
Мне интересно, почему NSUndoManager, по-видимому, забывает об элементах после их отмены и не позволяет выполнять повторные операции?
Следует упомянуть одну вещь: я отключаю отмену регистрации после открытия/создания документа.Когда я выполняю действие, я вызываю enableUndoRegistration
, beginUndoGrouping
, выполните действие, затем вызовите processPendingChanges
, setActionName:
, endUndoGrouping
, и наконец disableUndoRegistration
.Это гарантирует, что только определенные действия будут невыполнимыми, а любые другие изменения данных, которые я делаю за их пределами, останутся незамеченными для NSUndoManager.Это может быть частью проблемы, но если да, то мне интересно, почему это влияет на повтор?
Заранее спасибо.
Решение 2
Я исправил эту проблему:
Регистрация отмены всегда включена, за исключением тех случаев, когда я явно не хочу записывать отмены.
Я узнал, что:
Если вы включите регистрацию отмены непосредственно перед выполнением изменений, которые вы хотите записать, и отключите сразу после фиксации этих изменений, стек повторов NSUndoManager никогда не будет заполнен.
Так что никогда не звони disableUndoRegistration
.
Другие советы
На самом деле, если вы вызываете EnableUndoRegistration перед -undo и -redo (и DisableUndoRegistration после них), вы можете добиться того, чего хотели.
Я полагаю, что вы вызывали Enable(/disable)UndoRegistration только до и после изменений в ваших управляемых объектах.Это означает, что ваша «отмена» не была зарегистрирована в менеджере отмены, и, следовательно, вы не могли ее «повторить».
Я вызвал DisableUndoManager, оставив включенным «Повторить».Для этого я создал подкласс NSUndoManager и включил этот метод:
-(void) undo
{
[[appDelegate managedObjectContext] processPendingChanges];
[self enableUndoRegistration];
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate date]];
[super undo];
[[appDelegate managedObjectContext] processPendingChanges];
[self disableUndoRegistration];
}
Как заявил Стефанф в NSUndoManager, основные данные и выборочная отмена/повтор действия:«NSUndoManager ждет следующего цикла цикла выполнения, пока не зарегистрирует ваши изменения»