IOS设计模式第十篇之命令行设计模式
命令行设计模式:
命令设计模式将一个请求或行动作封装为对象。这个封装请求比原始的请求要灵活并且可以在对象之前被传递,存储,动态修改或者放进队列里面。苹果
苹果公司实现这种模式使用Target-Action机制和Invocation。
你可以阅读更多关于Target-Action机制在苹果的文档但是Invocation类可以包含一个目标对象,方法选择器和一些参数。当需要的时候这个对象可以被动态的改变。
这是一个完美的命令模式的例子。它将发送对象从接收对象和对象和可以持续请求或一连串的请求。
怎么使用命令设计模式?
在你进入invocation 操作之前。你需要设置framework来支持撤销操作。你必须定义一个UIToolBar 和NSMutableArray 来作为撤销栈。
在Viewcontroller实现文件延展里添加其他的实例变量:
UIToolbar *toolbar;
// We will use this array as a stack to push and pop operation for the undo option
NSMutableArray *undoStack;
创建一个toolbar 来展示按钮和新的操作。以及一个数组作为命令队列。
添加下面代码在ViewDidLoad:
toolbar = [[UIToolbar alloc] init];
UIBarButtonItem *undoItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemUndo target:self action:@selector(undoAction)];
undoItem.enabled = NO;
UIBarButtonItem *space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *delete = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(deleteAlbum)];
[toolbar setItems:@[undoItem,space,delete]];
[self.view addSubview:toolbar];
undoStack = [[NSMutableArray alloc] init];
上面代码创建一个toolbar带两个按钮和在他们之间添加一个灵活的空间。它还创建一个空撤销堆栈。这里的撤销按钮被禁用,因为撤销堆栈开始空了。
注意,工具栏没有用坐标初始化,由于在ViewDidLoad设置的坐标大小不是最终的。因此最后的设置通过下面代码:
- (void)viewWillLayoutSubviews
{
toolbar.frame = CGRectMake(, self.view.frame.size.height-, self.view.frame.size.width, );
dataTable.frame = CGRectMake(, , self.view.frame.size.width, self.view.frame.size.height - );
}
您将添加三个ViewController方法。m处理专辑管理操作:添加、删除和撤销。
第一个方法用来添加新专辑
- (void)addAlbum:(Album*)album atIndex:(int)index
{
[[LibraryAPI sharedInstance] addAlbum:album atIndex:index];
currentAlbumIndex = index;
[self reloadScroller];
}
在这里你添加一个新专辑,并且设置为当前的索引,并且加载这个滑动视图。
下面是删除方法:
- (void)deleteAlbum
{
//
Album *deletedAlbum = allAlbums[currentAlbumIndex];
//
NSMethodSignature *sig = [self methodSignatureForSelector:@selector(addAlbum:atIndex:)];
NSInvocation *undoAction = [NSInvocation invocationWithMethodSignature:sig];
[undoAction setTarget:self];
[undoAction setSelector:@selector(addAlbum:atIndex:)];
[undoAction setArgument:&deletedAlbum atIndex:];
[undoAction setArgument:¤tAlbumIndex atIndex:];
[undoAction retainArguments];
//
[undoStack addObject:undoAction];
//
[[LibraryAPI sharedInstance] deleteAlbumAtIndex:currentAlbumIndex];
[self reloadScroller];
//
[toolbar.items[] setEnabled:YES];
}
对上面做下解释:
1:让这张专辑删除
2:定义一个NSMethodSignature 类型为了创建NSInvocation。为了撤销删除操作。这个
NSInvocation需要知道三个事情:选择器(什么消息被发送),目标(谁发送这个消息)还有消息的参数。这个例子中一旦你撤销删除
他消息发送删除的相反您需要添加删除专辑。
3:撤销操作被创建后添加到空栈里面。这个操作被调价到数组的组后,就像正常的栈。
4:
用libraryAPI来删除专辑从数据架构中并且加载滑动视图。
5:自撤销堆栈的操作,您需要启用撤销按钮
注意:对于NSInvocation你需要注意下面几点:
1:参数必须通过指针传递
2:参数从2的索引开始,指数0和1都保留在目标和选择器。
3:果有机会,参数将被收回,那么你应该叫retainArguments。
最后添加撤销操作:
- (void)undoAction
{
if (undoStack.count > )
{
NSInvocation *undoAction = [undoStack lastObject];
[undoStack removeLastObject];
[undoAction invoke];
}
if (undoStack.count == )
{
[toolbar.items[] setEnabled:NO];
}}
撤消操作“弹出”中的最后一个对象栈。这个对象总是NSInvocation类型,可以通过调用调用…调用。这张专辑删除时调用的命令很早被创建。并添加删除专辑专辑列表。因为你也删除最后一个对象在堆栈“弹出”时,你现在看看栈是空的。如果是,这就意味着没有更多的行动取消。所以你禁用撤销按钮。构建和运行您的应用程序来测试你的撤销机制,删除一个专辑(或两个),点击取消按钮看它的实际应用:

这也是一个不错的测试是否保留更改相册数据之间的会话。现在,如果你删除一个专辑,将应用程序发送到后台,然后终止应用程序,下次启动应用程序显示专辑列表应该反映删除。
IOS设计模式第十篇之命令行设计模式的更多相关文章
- iOS系统提供开发环境下命令行编译工具:xcodebuild
iOS系统提供开发环境下命令行编译工具:xcodebuild[3] xcodebuild 在介绍xcodebuild之前,需要先弄清楚一些在XCode环境下的一些概念[4]: Workspace:简单 ...
- Noah的学习笔记之Python篇:命令行解析
Noah的学习笔记之Python篇: 1.装饰器 2.函数“可变长参数” 3.命令行解析 注:本文全原创,作者:Noah Zhang (http://www.cnblogs.com/noahzn/) ...
- Redis进阶实践之十五 Redis-cli命令行工具使用详解第二部分(结束)
一.介绍 今天继续redis-cli使用的介绍,上一篇文章写了一部分,写到第9个小节,今天就来完成第二部分.话不多说,开始我们今天的讲解.如果要想看第一篇文章,地址如下:http: ...
- Redis进阶实践之十四 Redis-cli命令行工具使用详解第一部分
一.介绍 redis学了有一段时间了,以前都是看视频,看教程,很少看官方的东西.现在redis的东西要看的都差不多看完了.网上的东西也不多了.剩下来就看看官网的东西吧,一遍翻译,一遍测试. ...
- Redis进阶实践之十四 Redis-cli命令行工具使用详解
转载来源:http://www.cnblogs.com/PatrickLiu/p/8508975.html 一.介绍 redis学了有一段时间了,以前都是看视频,看教程,很少看官方的东西.现在redi ...
- JMeter 十二:命令行执行
参考文档:http://jmeter.apache.org/usermanual/get-started.html#non_gui 真正开始跑压力测试时,我们就不能使用GUI模式了.这时候需要采用命令 ...
- jmeter(十)JMeter 命令行(非GUI)模式
前文 讲述了JMeter分布式运行脚本,以更好的达到预设的性能测试(并发)场景.同时,在前文的第一章节中也提到了 JMeter 命令行(非GUI)模式,那么此文就继续前文,针对 JMeter 的命令行 ...
- golang开发:类库篇(三)命令行工具cli的使用
为什么要使用命令行 觉得这个问题不应该列出来,又觉得如果初次进行WEB开发的话,可能会觉得所有的东西都可以使用API去做,会觉得命令行没有必要. 其实,一个生产的项目命令行是绕不过去的.比如运营需要导 ...
- JVM 第五篇:命令行 JVM 故障处理工具
本文内容过于硬核,建议有 Java 相关经验人士阅读. 1. 引言 虽然我们前面介绍了各种图形化 JVM 故障处理工具,但是很多情况下,我们在处理问题的时候并没有图形化的操作环境可以使用,这时候,就需 ...
随机推荐
- 第三百四十节,Python分布式爬虫打造搜索引擎Scrapy精讲—css选择器
第三百四十节,Python分布式爬虫打造搜索引擎Scrapy精讲—css选择器 css选择器 1. 2. 3. ::attr()获取元素属性,css选择器 ::text获取标签文本 举例: extr ...
- (转)st(state-threads) coroutine和stack分析
目录(?)[-] STACK分配 THREAD初始化栈 Thread启动和切换 Thread退出 Thread初始线程 Thread生命周期 st(state-threads) https://gi ...
- javascript -- canvas绘制曲线
绘制曲线有几种思路: 1.通过quadraticCurveTo(controlX, controlY, endX, endY)方法来绘制二次曲线 2.通过bezierCurveTo(controlX1 ...
- XSD 数据类型
字符串数据类型(String Data Type) 字符串数据类型可包含字符.换行.回车以及制表符. 下面是一个关于某个 scheme 中字符串声明的例子: <xs:element name=& ...
- 有术:DIY代理服务器
FQ有术:DIY代理服务器 公司HTTP代理穿透+手機ShadowSocks+SSH翻牆 利用SSH代理爬墙 http://bestvpnchina.net/
- js 事件详解 冒泡
起因:正常情况下我点击s2时是先弹出我是children,再弹出我是father,但是却出现了先弹出我是father,后弹出我是children的情况,这种情况是在和安卓app交互的h5页面中出现的, ...
- SVN自动生成版本号信息
在平时的多版本开发过程中,需要通过版本号来定位到源码版本,便于定位问题.常规工程实践是设置版本号为X.Y.Z.N,一般X表示主版本号,Y表示子版本号,我一般将Z设为0,N为本次提交的SVN版本 ...
- lsof fuser
使用fuser 或 lsof在一个挂载点中查找已打开的文件 fuser -mv /usr 查看有哪些进程在运行/usr中资源 sync fuser -km /media/usbdisk U盘无法卸载
- 使用apache的poi实现导入导出excel
1.jar包:poi-3.14-20160307.jar.poi-ooxml-3.14-20160307.jar 2.导入(本例实现了解析excel生成List): @Override public ...
- 使用psutil库监控linux的系统资源和自定义进程的cpu 内存占用。
#coding=utf8 import time import psutil from pprint import pprint from logger_until import LoggerUnti ...