0

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

我不明白为什么 Object id 不同,尽管 Key id 保持不变。是否对对象进行了一些特殊的撤消/重做处理NSMutableDictionary

谢谢xonic

4

2 回答 2

2

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

于 2010-05-26T20:10:22.057 回答
1

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

于 2010-05-26T19:38:56.277 回答