[ios2]NSUndoManager 【转】
来源:互联网 发布:淘宝摄影市场 编辑:程序博客网 时间:2024/04/30 11:19
在Cocoa中使用NSUndoManager可以很方便的完成撤销操作。NSUndoManager会记录下修改、撤销操作的消息。这个机制使用两个NSInvocation对象栈。
NSInvocation会把消息(选择器和接受者及参数)包装成一个对象,这个对象就是NSInvocation的实例。当一个对象收到它不理解的消 息时,消息发送机制会在报出错误前检查该对象是否实现了forwardInvocation这个方法。如果实现了,就会将消息打包成 NSInvocation对象,然后调用forwardInvocation方法。
当进行操作时,控制器会添加一个该操作的逆操作的invocation到Undo栈中。当进行Undo操作时,Undo操作的逆操作会倍添加到Redo栈中,就这样利用Undo和Redo两个堆栈巧妙的实现撤销操作。
这里需要注意的是,堆栈中存放的都是NSInvocation实例。
假设在我们的程序中有walkLeft以及这个方法的逆方法walkRight,我们可以这样来实现撤销功能。
- (void) walkLeft
{
position = position + 10;
[[undoManager prepareWithInvocationTarget:self] walkRight];
[self showTheChangesToThePostion];
}
prepareWithInvocationTarget:方法记录了target并返回UndoManager,然后UndoManager重载了 forwardInvocation方法,也就将walkRight方法的Invocation添加到undo栈中了。
- (void) walkRight
{
position = position - 10;
[[undoManager prepareWithInvocationTarget:self] walkLeft];
[self showTheChangesToThePostion];
}
[undoManager setActionName:@"Insert"];
//===一下是我在源代码网站里复制过来的代码,有学习价值====//
- (NSInvocation *) drawScribbleInvocation
{
NSMethodSignature *executeMethodSignature = [scribble_
methodSignatureForSelector:
@selector(addMark:
shouldAddToPreviousMark:)];
NSInvocation *drawInvocation = [NSInvocation
invocationWithMethodSignature:
executeMethodSignature];
[drawInvocation setTarget:scribble_];
[drawInvocation setSelector:@selector(addMark:shouldAddToPreviousMark:)];
BOOL attachToPreviousMark = NO;
[drawInvocation setArgument:&attachToPreviousMark atIndex:3];
return drawInvocation;
}
{
NSMethodSignature *executeMethodSignature = [scribble_
methodSignatureForSelector:
@selector(addMark:
shouldAddToPreviousMark:)];
NSInvocation *drawInvocation = [NSInvocation
invocationWithMethodSignature:
executeMethodSignature];
[drawInvocation setTarget:scribble_];
[drawInvocation setSelector:@selector(addMark:shouldAddToPreviousMark:)];
BOOL attachToPreviousMark = NO;
[drawInvocation setArgument:&attachToPreviousMark atIndex:3];
return drawInvocation;
}
- (NSInvocation *) undrawScribbleInvocation
{
NSMethodSignature *unexecuteMethodSignature = [scribble_
methodSignatureForSelector:
@selector(removeMark:)];
NSInvocation *undrawInvocation = [NSInvocation
invocationWithMethodSignature:
unexecuteMethodSignature];
[undrawInvocation setTarget:scribble_];
[undrawInvocation setSelector:@selector(removeMark:)];
return undrawInvocation;
}
{
NSMethodSignature *unexecuteMethodSignature = [scribble_
methodSignatureForSelector:
@selector(removeMark:)];
NSInvocation *undrawInvocation = [NSInvocation
invocationWithMethodSignature:
unexecuteMethodSignature];
[undrawInvocation setTarget:scribble_];
[undrawInvocation setSelector:@selector(removeMark:)];
return undrawInvocation;
}
调用:
[self executeInvocation:drawInvocation withUndoInvocation:undrawInvocation];
- (void) executeInvocation:(NSInvocation *)invocation
withUndoInvocation:(NSInvocation *)undoInvocation
{
[invocation retainArguments];
[[self.undoManager prepareWithInvocationTarget:self]
unexecuteInvocation:undoInvocation
withRedoInvocation:invocation];
[invocation invoke];
}
- (void) unexecuteInvocation:(NSInvocation *)invocation
withRedoInvocation:(NSInvocation *)redoInvocation
{
[[self.undoManager prepareWithInvocationTarget:self]
executeInvocation:redoInvocation
withUndoInvocation:invocation];
[invocation invoke];
}
withUndoInvocation:(NSInvocation *)undoInvocation
{
[invocation retainArguments];
[[self.undoManager prepareWithInvocationTarget:self]
unexecuteInvocation:undoInvocation
withRedoInvocation:invocation];
[invocation invoke];
}
- (void) unexecuteInvocation:(NSInvocation *)invocation
withRedoInvocation:(NSInvocation *)redoInvocation
{
[[self.undoManager prepareWithInvocationTarget:self]
executeInvocation:redoInvocation
withUndoInvocation:invocation];
[invocation invoke];
}
转载:http://www.cnblogs.com/jinjiantong/archive/2013/06/06/3120386.html
- [ios2]NSUndoManager 【转】
- [ios2]NSUndoManager 【转】
- NSUndoManager
- NSUndoManager
- NSUndoManager
- [ios2]蓝牙通信【转】
- [ios2] 开发技巧【转】
- [ios2] CABasicAnimation【转】
- [ios2]UItableview相关 【转】
- [ios2] ios7UI适配 【转】
- [ios2] 关于CGBitmapContextCreate【转】
- [ios2]BaaS服务收藏 【转】
- [ios2] ios7UI适配 【转】 - 金建彤
- [ios2]开发中用到的函数【转】
- [ios2]IOS NSInvocation用法简介【转】
- [ios2] iOS图片拉伸技巧 【转】
- [ios2]iOS 图片与内存 【转】
- [ios2][转]iOS摇动检测 (UIAccelerometer)
- Android, 如何在C文件中加log
- Mysql数据库的索引原理
- IOS设计模式学习(6)生成器
- sprintf 可变参数
- UBOOT详细解读
- [ios2]NSUndoManager 【转】
- JS:获取元素宽度高度
- html5 CSS过度-webkit-transition
- Updating Maven Project". Unsupported IClasspathEntry kind=4错误解
- Linux中的中断处理
- 文本 字符编码
- 【Zigbee】IAR基本配置(陆续添加)
- LABjs浅析
- Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1