NSUndoManager不会撤消NSMutableDictionary的编辑

时间:2010-05-26 19:26:40

标签: objective-c cocoa undo redo

我遇到了撤消操作的问题。以下代码不会撤消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

虽然密钥ID保持不变,但我不明白为什么Object id不同。是否对NSMutableDictionary个对象进行了一些特殊的撤消/重做处理?

THX xonic

2 个答案:

答案 0 :(得分:2)

听起来NSUndoManager正在做它的工作,但是当它移除值时,字典中没有NSBezierPath键的对象。我的猜测是NSBezierPath不能安全地用作字典键。您用作键的NSBezierPath对象可能在赋值和撤消之间的某处发生变异,这意味着当您到达hash时它的removeFromDictionary:方法不同,并且您不再有意义字典键。相反,尝试使用以某种方式与贝塞尔曲线路径相关联的NSString或NSNumber作为字典键。

答案 1 :(得分:1)

在一个示例中,您正在记录[currentPath objectAtIndex:0]的地址,而在另一个示例中,您正在从字典中记录任意键的地址(甚至不是值,而是随机键)。我没有理由在代码中看到为什么这些应该是同一个东西。