IOS设计模式第七篇之观察者设计模式
版权声明:原创作品,谢绝转载!否则将追究法律责任。
观察者设计模式
在观察者设计模式里面,一个对象通知其他的对象一些状态的改变。涉及这些对象不需要知道另一个对象---因此鼓励解耦设计模式。这个设计模式经常被用来通知感兴趣的对象当一个属性被改变时候。
通常实现需要一个观察者注册另一个对象感兴趣的状态。当状态改变,所有的观察者对象被通知改变了。苹果的远程通知服务就是一个全球性的例子。
如果你一直坚持MVC的概念,你需要允许你的model对象和View对象通信,但是不能直接引用,这就是观察者设计模式的由来。
cocoa实现观察者有两个相似的方法:通知和键值观察:
通知:不要被本地通知和远程通知迷惑,通知是根据订阅和通知的模式允许一个对象(通知者)发送消息给另一些对象(订阅者也就是监听者)。这个通知者不需要知道订阅者的任何信息。
苹果公司大量的使用通知,例如当键盘隐藏时候系统发送一个UIKeyboardWillShowNotification/UIKeyboardWillHideNotification通知。当你的应用进入后台系统发送一个UIApplicationDidEnterBackgroundNotification 通知。
打开UIApplication头文件。在文件最后你会看到系统发出的20个通知。
怎么使用通知呢
在AlbumView实现文件里面插入下面代码在[self addSubview:indicator];后面initWithFrame:albumCover:里面
[[NSNotificationCenter defaultCenter] postNotificationName:@"BLDownloadImageNotification"
object:self
userInfo:@{@"imageView":coverImage, @"coverUrl":albumCover}];
这一行通过NSNotificationCenter 的一个单例发送一个通知。这个通知包含了一个UIImageView用来填充专辑封面和一个下载图片的URL。这里面的所有信息你需要在你的下载任务里面执行。
在libraryAPI实现文件里面的init方法isOnline = NO:后面添加下面代码:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadImage:) name:@"BLDownloadImageNotification" object:nil];
这个就是观察者。每次AlbumView 类发送一个BLDownloadImageNotification 通知。这个libraryAPI为这个通知注册一个观察者。系统通知libraryAPI。并且libraryAPI执行downloadImage:作为回答。
然后在实现downloadImage:之前你必须取消你注册的这个通知当你的类销毁的时候。如果不这样做通知就会发送到一个销毁的对象。这就是应用崩溃的结果。
在libraryAPI实现文件里面添加下面代码:
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
当这个类销毁时候。他作为观察者从所有已经注册的通知中移除掉。还有一件事情要做,我们保存下载的图片。这样应用不需要下载相同的图片了。
打开
PersistencyManager有文件加入下面两个方法原型:
- (void)saveImage:(UIImage*)image filename:(NSString*)filename; - (UIImage*)getImage:(NSString*)filename;
实现文件里面:
- (void)saveImage:(UIImage*)image filename:(NSString*)filename { filename = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@", filename]; NSData *data = UIImagePNGRepresentation(image); [data writeToFile:filename atomically:YES]; } - (UIImage*)getImage:(NSString*)filename { filename = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@", filename]; NSData *data = [NSData dataWithContentsOfFile:filename]; return [UIImage imageWithData:data]; }
这段代码是下载图片保存在沙盒,并且如果沙盒没有这个图片路径就会返回nil。
下面在libraryAPI加入下面代码:
- (void)downloadImage:(NSNotification*)notification { // 1 UIImageView *imageView = notification.userInfo[@"imageView"]; NSString *coverUrl = notification.userInfo[@"coverUrl"]; // 2 imageView.image = [persistencyManager getImage:[coverUrl lastPathComponent]]; if (imageView.image == nil) { // 3 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ UIImage *image = [httpClient downloadImage:coverUrl]; // 4 dispatch_sync(dispatch_get_main_queue(), ^{ imageView.image = image; [persistencyManager saveImage:image filename:[coverUrl lastPathComponent]]; }); }); } }
具体解释上面代码
1:downloadImage 被执行通过通知因此接收这个通知对象作为参数:
2:如果之前已经下载图片那么从PersistencyManager 检索图片。
3:如果图片没有下载,那么再次用HTTPClient请求图片
4:当下载完成了在UIImageView里面显示图片并且用PersistencyManager 来保存图片。
我们再次用外观设计模式隐藏从一些类里面下载一个图片的复杂性。这个通知发送者不关心你的图片是从网络获取的还是从文件系统获得的。
编译运行你的应用看看你的专辑已经覆盖到你的滑动视图上。

再次停止并且运行他。注意没有延迟加载你的专辑因为他们已经保存到本地。你甚至可以断开网络链接你的应用还可以继续的完美运行着。但是你的网络提示器一直的旋转不停止了为什么呢?
当你开始下载图片,你没有实现当图片下载完停止网络提示器的旋转的逻辑。你不能每次都发送一个通知当图片下载完成了。然而我们可以用另一个观察者设计模式键值编码。
IOS设计模式第七篇之观察者设计模式的更多相关文章
- IOS设计模式第六篇之适配器设计模式
版权声明:原创作品,谢绝转载!否则将追究法律责任. 那么怎么使用适配器设计模式呢? 这个之前提到的水平滚动的视图像这样: 为了开始实现他,我们创建一个新的继承与UIView的HorizontalScr ...
- IOS设计模式第五篇之装饰设计模式的代理设计模式
版权声明:原创作品,谢绝转载!否则将追究法律责任. 代理: 另一个装饰设计模式,代理,是一个代表或者协调另一个对象的行为机制.例如当你用一个tableView,你必须实现他里面的一个tableView ...
- IOS设计模式第四篇之装饰设计模式的类别设计模式
装饰设计模式 装饰设计模式动态的添加行为和责任向一个对象而不修改他的任何代码.他是你子类化修改类的行为用通过另一个对象的包装的代替方法. 在Objective-c里面有很多这种设计模式的实现,像cat ...
- IOS设计模式第三篇之外观设计模式
外观设计模式: 这个外观设计模式提供了一个单独的接口给复杂的子系统.而不是暴露用户的一组类和API,你仅仅暴露一个简单的同一的API. 下面的图片解释这个概念: API的用户根本不知道后面系统的复杂性 ...
- 《Head First设计模式》批注系列(一)——观察者设计模式
最近在读<Head First设计模式>一书,此系列会引用源书内容,但文章内容会更加直接,以及加入一些自己的理解. 观察者模式(有时又被称为模型-视图(View)模式.源-收听者(List ...
- php设计模式笔记--总结篇
一.引入 设计模式的一般定义不再说,只大概说一下我理解的设计模式,我理解的设计模式的主要目的是利用面向对象(类.接口等)特点,让代码更加易于扩展,易于重用,易于维护.这三个特点也就要求我们不要将太多 ...
- javaEE之--------统计站点在线人数,安全登录等(观察者设计模式)
整体介绍下: 监听器:监听器-就是一个实现待定接口的普通Java程序,此程序专门用于监听别一个类的方法调用.都是使用观察者设计模式. 小弟刚接触这个,做了些简单的介绍.大神请绕道,技术仅仅是一点点, ...
- JAVA设计模式---总述篇
一.设计模式(Design Pattern): 1.设计模式的概念 是前辈们对代码开发经验的总结,是解决特定问题的一系列套路.它不是语法规定,而是一套用来提高代码可复用性.可维护性.可读性.稳健性以及 ...
- 【设计模式】第一篇:概述、耦合、UML、七大原则,详细分析总结(基于Java)
迷茫了一周,一段时间重复的 CRUD ,着实让我有点烦闷,最近打算将这些技术栈系列的文章先暂时搁置一下,开启一个新的篇章<设计模式>,毕竟前面写了不少 "武功招式" 的 ...
随机推荐
- e768. 创建单选按钮
// Create an action for each radio button Action action1 = new AbstractAction("RadioButton Labe ...
- TPshop的规格表设计原理机制
TPshop商品规格比较简单, 数据库设计清晰, 先看上图购买商品时对应的选择, 不同规格有着不同的价格和不同的库存. 再看看后台对应的设置,手机例子 颜色:黑色 白色 金色 内存:32G 64G ...
- (原)关于sdl在部分机器上做视频显示,改变显示窗口大小会崩溃
今天测试人员反应,之前做的视频绘图显示,会在她机器上,会出现崩溃现象,最后我在她机器上对代码进行跟踪,发现在某种情况,确实会崩溃. 最主要的原因是,视频显示窗口变成非活动窗口的时候,sdl内部会循环消 ...
- Java设计模式六大原则之场景应用分析
定义:不要存在多于一个导致类变更的原因. 通俗的说.即一个类仅仅负责一项职责. 问题由来:类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而须要改动类T时,有可能会导致原本执行正 ...
- SQL Server 定时执行SQL语句的方法
SQL SERVER 定时任务,你可以启动一下.不过要想更加直观的控制,直接写一个程序,定时执行你的存储过程. 1.设置“SQL Server 代理”(SQL Server Agent)服务随系统启动 ...
- linux静止ping的方法
ping是一个通信协议,是ip协议的一部分,tcp/ip 协议的一部分.利用它可以检查网络是否能够连通,用好它可以很好地帮助我们分析判定网络故障.应用格式为:Ping IP地址.但服务启用ping有时 ...
- Nginx访问日志 Nginx日志切割 静态文件不记录日志和过期时间
- css box-shadow添加阴影
基础说明: 外阴影:box-shadow: X轴 Y轴 Rpx color; 属性说明(顺序依次对应): 阴影的X轴(可以使用负值) 阴影的Y轴(可以使用负值) 阴影 ...
- 通过tarball形式安装HBASE Cluster(CDH5.0.2)——配置分布式集群中的YARN ResourceManager 的HA
<?xml version="1.0"?> <!-- Licensed under the Apache License, Version 2.0 (the &q ...
- mysql中explain
1.select_type: /* select_type 使用 SIMPLE */explain select * from tb_shop_order where id='201603292570 ...