NSUndoManager con Core Data - Redo non funziona
-
19-09-2019 - |
Domanda
Ho un'applicazione basata su documenti Core Data che supportano undo / redo tramite il built-in NSUndoManager associato alla NSManagedObjectContext. Ho un paio di azioni costituite che svolgono numerosi compiti all'interno di Core Data, avvolgono tutti questi compiti in un gruppo di undo tramite beginUndoGrouping
/ endUndoGrouping
, e vengono elaborati dal NSUndoManager.
Annulla funziona bene. Posso eseguire diverse azioni successive, e ciascuno poi annullare ognuna di esse in successione e lo stato della mia app viene mantenuto correttamente. Tuttavia, la voce di menu "Ripristina" non è mai attivato. Ciò significa che il NSUndoManager sta dicendo il menu che non ci sono elementi da rifare.
Mi chiedo perché il NSUndoManager è apparentemente dimenticando oggetti una volta che sono annullate, e non permettendo redos a verificarsi?
Una cosa che vorrei menzionare è che sto disattivando annullare la registrazione dopo si apre un documento / creato. Quando si esegue un'azione, che io chiamo enableUndoRegistration
, beginUndoGrouping
, eseguire l'azione, quindi chiamare processPendingChanges
, setActionName:
, endUndoGrouping
, e, infine, disableUndoRegistration
. Questo fa in modo che solo le azioni specifiche sono annullabile, e tutte le altre modifiche di dati che faccio al di fuori di questi passano inosservati al NSUndoManager. Questo può essere una parte del problema, ma se è così mi chiedo perché sta interessando rifare?
Grazie in anticipo.
Soluzione 2
Ho fissato questo problema:
Mantenere annullare registrazione abilitato per tutto il tempo, tranne che per i tempi in cui ho esplicitamente non voglio registrare annullamenti.
Ho imparato che:
Se si abilita annullare la registrazione poco prima di eseguire le modifiche che si desidera registrare, e disattivare subito dopo aver commesso tali modifiche, pila redo del NSUndoManager non viene mai popolato.
Quindi, non chiamare disableUndoRegistration
.
Altri suggerimenti
In realtà, a patto che si chiama enableUndoRegistration prima sia -undo e -redo (e disableUndoRegistration dopo di loro), è possibile ottenere quello che cercavamo.
Credo che si stava solo chiamando abilitare (/ disabilitazione) UndoRegistration prima e dopo le modifiche ai oggetti gestiti. Ciò significa che il 'annullare' non è stato registrato con il gestore di annullamento, e quindi non si poteva 'rifare' esso.
Ho chiamato disableUndoManager mantenendo "Ripeti" abilitato. Per fare questo ho sottoclasse NSUndoManager e incluso questo metodo:
-(void) undo
{
[[appDelegate managedObjectContext] processPendingChanges];
[self enableUndoRegistration];
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate date]];
[super undo];
[[appDelegate managedObjectContext] processPendingChanges];
[self disableUndoRegistration];
}
Come affermato da Stefanf in NSUndoManager, Core Data e selettivo undo / redo : "NSUndoManager attende il prossimo ciclo di ciclo di esecuzione fino a quando non registra le modifiche"