2010-03-10 6 views
1

J'ai une application de base de données de données qui supporte annuler/rétablir via le NSUndoManager intégré associé à NSManagedObjectContext. J'ai quelques actions mises en place qui effectuent de nombreuses tâches dans les données de base, enveloppent toutes ces tâches dans un groupe undo via beginUndoGrouping/endUndoGrouping et sont traitées par le NSUndoManager.NSUndoManager avec Core Data - Redo ne fonctionne pas

Annuler fonctionne très bien. Je peux effectuer plusieurs actions successives, puis chacune d'entre elles les annule successivement et l'état de mon application est correctement maintenu. Cependant, l'élément de menu "Rétablir" n'est jamais activé. Cela signifie que NSUndoManager indique au menu qu'il n'y a aucun élément à rétablir.

Je me demande pourquoi NSUndoManager oublie apparemment des éléments une fois qu'ils sont annulés, et ne permet pas de faire des redos?

Une chose que je devrais mentionner est que je désactive l'enregistrement d'annulation après qu'un document soit ouvert/créé. Lorsque j'effectue une action, j'appelle enableUndoRegistration, beginUndoGrouping, exécute l'action, puis appelle le processPendingChanges, setActionName:, endUndoGrouping, et enfin disableUndoRegistration. Cela fait en sorte que seules les actions spécifiques peuvent être annulées, et toute autre modification de données que je fais en dehors de ceux-ci passent inaperçues au NSUndoManager. Cela peut être une partie du problème, mais si oui, je me demande pourquoi cela affecte redo?

Merci d'avance.

Répondre

1

J'ai résolu ce problème par:

enregistrement Tenue undo a permis tout le temps, à l'exception des moments où je ne veux pas explicitement d'enregistrer undos.

J'ai appris que:

Si vous activez annuler l'enregistrement juste avant d'effectuer les modifications que vous souhaitez enregistrer, et de désactiver immédiatement après avoir commis ces changements, la pile de rétablissement de la NSUndoManager n'est jamais peuplée.

Ainsi, n'appelez jamais disableUndoRegistration.

3

En fait, tant que vous appelez enableUndoRegistration avant à la fois -undo et -redo (et disableUndoRegistration après eux), vous pouvez obtenir ce que vous recherchiez.

Je crois que vous n'appeliez qu'activer (/ désactiver) UndoRegistration avant et après les modifications apportées à vos objets gérés. Cela signifie que votre 'Annuler' n'était pas enregistré avec le gestionnaire d'annulation, et que vous ne pouviez donc pas le 'refaire'.

1

J'ai appelé disableUndoManager tout en gardant "Redo" activé. Pour ce faire, je NSUndoManager et sous-classé inclus cette méthode:

-(void) undo 
{ 
    [[appDelegate managedObjectContext] processPendingChanges]; 
    [self enableUndoRegistration]; 
    [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate date]]; 
    [super undo]; 
    [[appDelegate managedObjectContext] processPendingChanges]; 
    [self disableUndoRegistration]; 
} 

Comme indiqué par stefanf dans NSUndoManager, Core Data and selective undo/redo: « NSUndoManager attend le prochain cycle de boucle d'exécution jusqu'à ce qu'il enregistre vos modifications »