NSUndoManager не отменяет редактирование NSMutableDictionary - PullRequest
0 голосов
/ 26 мая 2010

У меня проблемы с операцией отмены. Следующий код не отменяет операцию removeObjectForKey:, но операция восстановления setObject:ForKey: работает.

 - (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];

}

Вывод на консоль выглядит так:

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

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

Я не понимаю, почему идентификатор объекта отличается, хотя идентификатор ключа остается прежним. Есть ли специальная обработка отмены / повторения NSMutableDictionary объектов?

ТНХ xonic

Ответы [ 2 ]

2 голосов
/ 27 мая 2010

Звучит так, будто NSUndoManager выполняет свою работу, но когда пришло время удалить значение, в словаре нет объекта для ключа NSBezierPath. Я предполагаю, что NSBezierPath не безопасно использовать в качестве словарного ключа. Объект NSBezierPath, который вы используете в качестве ключа, вероятно, видоизменяется где-то между присваиванием и отменой, что означает, что его метод hash отличается к тому времени, когда вы достигаете removeFromDictionary:, и у вас больше нет значимого словарного ключа. Вместо этого попробуйте использовать NSString или NSNumber, который каким-то образом связан с путем Безье, в качестве ключа словаря.

1 голос
/ 26 мая 2010

В одном примере вы регистрируете адрес [currentPath objectAtIndex:0], а в другом - адрес произвольного ключа (даже не значения, а случайного ключа) из словаря.В коде нет причин видеть, почему это должно быть одно и то же.

...