2010-05-26 42 views
0

Je rencontre des problèmes avec l'opération d'annulation. Le code suivant n'annulera pas une opération removeObjectForKey: mais l'opération de rétablissement setObject:ForKey: fonctionne.NSUndoManager n'annulera pas l'édition d'un NSMutableDictionary

- (void) insertIntoDictionary:(NSBezierPath *)thePath 
{ 
[[[window undoManager] prepareWithInvocationTarget:self] removeFromDictionary:thePath]; 

if(![[window undoManager] isUndoing]) 
    [[window undoManager] setActionName:@"Save Path"]; 

NSLog(@"Object id is: %d and Key id is: %d", [currentPath objectAtIndex:0], thePath); 

[colorsForPaths setObject:[currentPath objectAtIndex:0] forKey:thePath]; 
} 

- (void) removeFromDictionary:(NSBezierPath *)thePath 
{ 
[[[window undoManager] prepareWithInvocationTarget:self] insertIntoDictionary:thePath]; 

if(![[window undoManager] isUndoing]) 
    [[window undoManager] setActionName:@"Delete Path"]; 

NSLog(@"Object id is: %d and Key id is: %d", [colorsForPaths objectForKey:thePath], thePath); 

[colorsForPaths removeObjectForKey:thePath]; 

} 

La sortie sur la console ressemble à:

// Before setObject:ForKey: 
Object id is: 1183296 and Key id is: 1423872 

// Before removeObjectForKey: 
UNDO 
Object id is: 0 and Key id is: 1423872 

Je ne comprends pas pourquoi l'ID d'objet est différent, bien que l'ID de clé reste le même. Y a-t-il un traitement spécial annuler/rétablir des objets NSMutableDictionary?

thx xonic

Répondre

1

Dans un exemple, vous vous connectez l'adresse de [currentPath objectAtIndex:0], et dans l'autre, vous vous connectez l'adresse d'une clé arbitraire (même pas une valeur, mais une clé aléatoire) de la dictionnaire. Il n'y a aucune raison que je puisse voir dans le code pourquoi cela devrait être la même chose.

+0

Ah sacrément, désolé à ce sujet ... avait un extrait de gauche de jouer avec le code. Je suis fatigué, je suppose :) J'ai maintenant corrigé le code, mais le résultat ne fonctionne toujours pas. Thx – xon1c

2

Il semble que NSUndoManager fasse son travail, mais quand il est temps de supprimer la valeur, il n'y a aucun objet dans le dictionnaire pour la clé NSBezierPath. Ma conjecture est que NSBezierPath n'est pas sûr à utiliser comme une clé de dictionnaire. L'objet NSBezierPath que vous utilisez comme clé est probablement muté quelque part entre affectation et annulation, ce qui signifie que sa méthode hash est différente au moment où vous atteignez removeFromDictionary:, et que vous n'avez plus de clé de dictionnaire significative. Au lieu de cela, essayez d'utiliser un NSString ou NSNumber qui est en quelque sorte associé au chemin bezier comme une clé de dictionnaire.

+0

Thx pour votre saisie. En fait, je ne suis pas sûr que ce soit vraiment le problème. D'une part j'ai le même appel [colorsForPaths objectForKey: thePath] dans un fichier différent (la vue) qui renvoie l'objet correct, mais d'autre part l'opération de refaire enregistre l'id NSBezierPath correct et insère l'objet correct dans le dictionnaire même si cet objet est alors deux fois dans le dictionnaire et n'est pas écrasé par le nouvel objet refait (même). – xon1c