作者yllan (蓝永伦)
看板MacDev
标题Re: [问题] 关於redo
时间Mon May 7 11:10:37 2007
※ 引述《Devon22 ()》之铭言:
: 请教一下yllan大关於redo的写法
: undo的部份我是用registerUndoWithTarget:selector:object:
: 那redo的部份应该要怎麽处理呢?
: 文件里面关於redo的部份好少,实在不晓得应该怎麽写...
直接用 [NSUndoManager redo] 就可~怎麽说呢? NSUndoManager 是
这样设计的:
假设你有个 Model Class, 叫做 MoneyBook,其中有个 method 叫做
setData: (id) newData 好了。现在我希望 MoneyBook 的 setData
能做 undo ,就这麽写:
- (void) setData: (id) newData {
[myUndoManager registerUndoWithTarget: self
selector: @selector(setData:)
object:
oldData ];
id temp = oldData;
oldData = [newData retain];
[temp release];
}
假设一开始 MoneyBook 的 data 是 @"OLD" 好了,现在我们执行
[myMoneyBook setData: @"NEW"]
希望将来 undo 的时候可以恢复到 @"OLD",所以 register.... 的时
後注意黄字,我们是把旧的值存下来。
於是 NSUndoManager 就纪录下来一个 undo 动作了,这个 undo 其实
就是把 (myMoneyBook, "setData:", @"OLD") 记录下来,等到呼叫
[myUndoManager undo]
的时候,他就会找到最近纪录的一群 undo ,invoke:
[myMoneyBook setData: @"OLD"]
注意此时 setData: 里的 oldData == @"NEW",newData == @"OLD"!
於是他又会再一次执行 register.... ,只是这次是纪录
(myMoneyBook, "setData:", @"NEW") ,而且 NSUndoManager 会知道说
这次纪录的东西是由 undo 所引发的,因此这个纪录要记在 redo stack。
所以呼叫 [myUndoManager redo] 的时候,就会呼叫
[myMoneyBook setData: @"NEW"]
了。
所以说也不是这麽简单随便用 redo 就行,而是你必须遵循 Apple 的
implicit pattern 来设计程式。不过说穿了就是 MVC,你在 model 中
accessor/会改变状态的地方,插入 register.... 叙述,并且要是
「自己这个 method with old data」,延用这个惯例就不用花脑筋了。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.31.182
1F:推 Devon22:原来redo也是同一段程式,不过看来似乎不太好改的样子.. 05/07 16:57