版权声明:原创作品,谢绝转载!否则将追究法律责任。

观察者设计模式

在观察者设计模式里面,一个对象通知其他的对象一些状态的改变。涉及这些对象不需要知道另一个对象---因此鼓励解耦设计模式。这个设计模式经常被用来通知感兴趣的对象当一个属性被改变时候。

通常实现需要一个观察者注册另一个对象感兴趣的状态。当状态改变,所有的观察者对象被通知改变了。苹果的远程通知服务就是一个全球性的例子。

如果你一直坚持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设计模式第七篇之观察者设计模式的更多相关文章

  1. IOS设计模式第六篇之适配器设计模式

    版权声明:原创作品,谢绝转载!否则将追究法律责任. 那么怎么使用适配器设计模式呢? 这个之前提到的水平滚动的视图像这样: 为了开始实现他,我们创建一个新的继承与UIView的HorizontalScr ...

  2. IOS设计模式第五篇之装饰设计模式的代理设计模式

    版权声明:原创作品,谢绝转载!否则将追究法律责任. 代理: 另一个装饰设计模式,代理,是一个代表或者协调另一个对象的行为机制.例如当你用一个tableView,你必须实现他里面的一个tableView ...

  3. IOS设计模式第四篇之装饰设计模式的类别设计模式

    装饰设计模式 装饰设计模式动态的添加行为和责任向一个对象而不修改他的任何代码.他是你子类化修改类的行为用通过另一个对象的包装的代替方法. 在Objective-c里面有很多这种设计模式的实现,像cat ...

  4. IOS设计模式第三篇之外观设计模式

    外观设计模式: 这个外观设计模式提供了一个单独的接口给复杂的子系统.而不是暴露用户的一组类和API,你仅仅暴露一个简单的同一的API. 下面的图片解释这个概念: API的用户根本不知道后面系统的复杂性 ...

  5. 《Head First设计模式》批注系列(一)——观察者设计模式

    最近在读<Head First设计模式>一书,此系列会引用源书内容,但文章内容会更加直接,以及加入一些自己的理解. 观察者模式(有时又被称为模型-视图(View)模式.源-收听者(List ...

  6. php设计模式笔记--总结篇

    一.引入  设计模式的一般定义不再说,只大概说一下我理解的设计模式,我理解的设计模式的主要目的是利用面向对象(类.接口等)特点,让代码更加易于扩展,易于重用,易于维护.这三个特点也就要求我们不要将太多 ...

  7. javaEE之--------统计站点在线人数,安全登录等(观察者设计模式)

    整体介绍下:  监听器:监听器-就是一个实现待定接口的普通Java程序,此程序专门用于监听别一个类的方法调用.都是使用观察者设计模式. 小弟刚接触这个,做了些简单的介绍.大神请绕道,技术仅仅是一点点, ...

  8. JAVA设计模式---总述篇

    一.设计模式(Design Pattern): 1.设计模式的概念 是前辈们对代码开发经验的总结,是解决特定问题的一系列套路.它不是语法规定,而是一套用来提高代码可复用性.可维护性.可读性.稳健性以及 ...

  9. 【设计模式】第一篇:概述、耦合、UML、七大原则,详细分析总结(基于Java)

    迷茫了一周,一段时间重复的 CRUD ,着实让我有点烦闷,最近打算将这些技术栈系列的文章先暂时搁置一下,开启一个新的篇章<设计模式>,毕竟前面写了不少 "武功招式" 的 ...

随机推荐

  1. Oracle两个数据库互相访问,DBLink使用-转

    测试条件:假设某公司总部在北京,新疆有其下属的一个分公司.在本次测试中,新疆的计算机为本地计算机,即本要的IP地址为:192.168.1.100 北京的总部有一个集中的数据库,其SID是SIDBJ,用 ...

  2. tushare使用

    tushare是获取行情数据的一款免费软件 使用方法很简单, 先安装:pip install tushare 然后 import tushare as ts 即可.   data = ts.get_k ...

  3. (转)BT1120接口及协议

    因为项目上用到的是 海思3536的bt1120接口对接 FPGA.项目上用到的是 1920 x 1080,60Hz.逐隔. 上图看到, BT1120的接口 有 16根 数据线 和 一根 时钟线. 下面 ...

  4. css3 -- 自动生成序号(不使用JS,可任意排序)

    需求:一个table 需要在第一列生成序号:1.2.3.4.5......  并且自适应行数 不使用后台程序,开始考虑使用JS,但是一旦前台排序后,序号就乱了,最后采用CSS的一个计数器方法实现! & ...

  5. js 闭包实例

    var db = (function() { // 创建一个隐藏的object, 这个object持有一些数据 // 从外部是不能访问这个object的 var data = {}; // 创建一个函 ...

  6. JAVA的get post 区别

    1. get 是从服务器上获取数据,post 是向服务器传送数据. get 请求返回 request - URI 所指出的任意信息.Post 请求用来发送电子邮件.新闻或发送能由交互用户填写的表格.这 ...

  7. linux下nginx配置ssl证书(https)

    nginx配置ssl很简单,首先需要两个文件,一个是crt文件,另一个是key文件,如下所示: xxx.crt;  #(证书公钥)xxx.key; #(证书私钥) 把这两个文件放到nginx的conf ...

  8. windows 找不到文件'igfxHK.exe'

    现象:开机时windows报:windows 找不到文件'igfxHK.exe' 解决办法:win+r  输入services.msc  进入服务管理, 找到服务名称为: Intel(R) HD Gr ...

  9. hibernate DetachedCriteria 分页

    # 具有一个直观的.可扩展的条件查询API是Hibernate的特色. # # 15.1. 创建一个Criteria 实例 # org.hibernate.Criteria接口表示特定持久类的一个查询 ...

  10. LoadRunner做性能测试 从设计到分析执行

    项目简介:像百度知道系统类似的系统性能测试,是公司的自己产品. 对最近这个系统的性能测试进行总结下: 系统功能介绍: 前台用户可以根据自己的需要对不同的区域提问,提问包括匿名和登陆用户提问 后台不同区 ...