音效素材网提供各类素材,打造精品素材网站!

站内导航 站长工具 投稿中心 手机访问

音效素材

iOS应用开发中使用设计模式中的观察者模式的实例
日期:2016-03-17 09:52:37   来源:脚本之家

在软件开发中,无论是那种高级语言中总会伴随着一些最为常用的设计模式,即便就如iOS开发中与我们打交道最多的无非就是单例模式、观察者模式和工厂模式了,当然了其他的设置模式也同样存在在编程的很多地方。下面就就让我们简单的了解下观察者模式吧!
观察者模式本质上时一种发布-订阅模型,用以消除具有不同行为的对象之间的耦合,通过这一模式,不同对象可以协同工作,同时它们也可以被复用于其他地方Observer从Subject订阅通知,ConcreteObserver实现重现ObServer并将其重载其update方法。一旦SubJect的实例需要通知Observer任何新的变更,Subject会发送update消息来通知存储在其内部类中所注册的Observer、在ConcreteObserver的update方法的实际实现中,Subject的内部状态可被取得并进行后续处理。其类图如下:

201631795044843.jpg (737×317)


由上面我们可以发现观察者模式无非在是定义对象间的一种一对多的依赖关系,并且当一个对象的状态发生改变的时候,所有依赖于它的对象都会得到通知且自动更新。即如果Subject允许其他观察者(实现了观察者接口的对象)对这个Subject的改变进行请阅,当Subject发送了变化,那么Subject会将这个变化发送给所有的观察者,观察者就能对Subject的变化做出更新。其时序图如下

201631795111827.png (466×255)

通过上面的观察我们可以发现如果用N个Observer来拓展Subject的行为,这些Observer具有处理存储在Subject中的信息的特定实现,这样也就实现了前面所说的消除不同对象间的耦合的功能了。
那么了解了这些我们可能就会更像了解下我们在什么时候才会去使用观察者模式呢?
当需要将改变通知所有的对象时,而你又不知道这些对象的具体类型
改变发生在同一个对象中,并需要改变其他对象将相关的状态进行更新且不知道有多少个对象。
而同样的在我们日常的开发中在Cocoa Touch框架中的的两种经常打交道的技术KVO与通知都实现了观察者模式,所以下面我们讨论的重点也就是基于这两个方面的。
通知
言归正传,在Cocoa Touch框架中NSNotificationCenter和NSNotification对象实现了一对多的模型。通过NSNotificationCenter可以让对象之间进行通讯,即便这些对象之间并不认识。下面我们来看下NSNotificationCenter发布消息的方法:

复制代码 代码如下:

   NSNotification  * subjectMessage = [ NSNotification  notificationWithName:@"subjectMessage"  object: self];
    NSNotificationCenter  * notificationCenter = [ NSNotificationCenter  defaultCenter];
    [notificationCenter postNotification:subjectMessage];

通过上面的代码我们创建了一个名为subjectMessage的NSNotification对象,然后通过notificationCenter来发布这个消息。通过向NSNotificationCenter类发送defaulCenter消息,可以得到NSNotificationCenter实例的引用。每个进程中只有一个默认的通知中心,所以默认的NSNotificationCenter是个单例对象。如果有其他观察者定于了其对象的相关事件则可以通过以下的方法来进行操作:
复制代码 代码如下:

    NSNotificationCenter  * notificationCenter1 = [ NSNotificationCenter  defaultCenter];
    [notificationCenter addObserver: self  selector: @selector(update:) name:@"subjectMessage"  object: nil ];

经过以上步骤我们已经向通知中心注册了一个事件并且通过selector制定了一个方法update:下面我们可以实现以下这个方法
复制代码 代码如下:

- (void)update:(NSNotification*)notification{

        if ([[notification name] isEqualToString:@"subjectMessage"]) {
            NSLog(@"%@",@"猴子派来的救兵去哪了?");

        }
}


当然最后如果我们需要对监听进行销毁
复制代码 代码如下:

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

实例
抽象主题协议:

复制代码 代码如下:

#import <Foundation/Foundation.h> 
@class Observer; 
 
/*!
 *  抽象主题协议
 *
 *  @since V1.0
 */ 
@protocol Subject <NSObject> 
 
@required 
 
/*!
 *  增加观察者
 *
 *  @param observer 观察者实例
 *
 *  @since V1.0
 */ 
-(void)attach:(Observer*) observer; 
/*!
 *  移除观察者
 *
 *  @param observer 观察者实例
 *
 *  @since V1.0
 */ 
-(void)detach:(Observer*) observer; 
/*!
 *  为观察者发送通知
 *
 *  @since V1.0
 */ 
-(void)notifyObservers; 
 
@end 

观察者协议:
复制代码 代码如下:

#import <Foundation/Foundation.h> 
 
/*!
 *  观察者协议
 *
 *  @since V1.0
 */ 
@protocol Observer <NSObject> 
 
@required 
-(void)update; 
 
@end 

具体的观察者类:
复制代码 代码如下:

#import <Foundation/Foundation.h> 
#import "Observer.h" 
 
/*!
 *  具体的观察者类
 *
 *  @since V1.0
 */ 
 
@interface ConcreteObserver : NSObject<Observer> 
 
@end 

具体主题类:
复制代码 代码如下:

#import <Foundation/Foundation.h> 
#import "Subject.h" 
 
/*!
 *  具体主题类
 *
 *  @since V1.0
 */ 
@interface ConcreteSubject : NSObject<Subject> 

    NSMutableArray *observers; 

@property(nonatomic,strong)NSMutableArray* observers; 
/*!
 *  单例构建自身对象
 *
 *  @return 自身对象
 *
 *  @since V1.0
 */ 
+(ConcreteSubject*)shareConcreteSubject; 
 
@end 

了解过通知之后我们来看一下KVO
KVO是Cocoa提供的一种称为键值观察的机制,对象可以通过它得到其他对象特定属性的变更通知。而这个机制是基于NSKeyValueObserving非正式些,Cocoa通过这个协议为所有遵循协议的对象提供了一种自动化的属性监听的功能。
虽然通知和KVO都可以对观察者进行实现,但是他们之间还是略有不同的,由上面的例子我们可以看出通知是由一个中心对象为所有观察者提供变更通知,主要是广义上关注程序事件,而KVO则是被观察的对象直接想观察者发送通知,主要是绑定于特定对象属性的值。下面我们通过一个简单的例子来了解下他的一些是使用方法
首先我们有Hero这个模型

复制代码 代码如下:

@property (nonatomic,copy) NSString * name;@property (nonatomic,copy) NSString * title;@property (nonatomic,assign) NSUInteger age;

在控制其中我们将其初始化并赋值
复制代码 代码如下:

    self.hero = [[Hero alloc] init];
    self.hero.name = @"赵云";
    self.hero.title = @"将军";
    self.hero.age = 87;

现在我们的这个对象基本有值了,那么我们将这个对象的name监听下他的改变
复制代码 代码如下:

[self.hero addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

触发通知并将值改变
复制代码 代码如下:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    self.hero.name = @"张飞";
}

在制定的回调函数中,处理收到的更改通知
复制代码 代码如下:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    if([keyPath isEqualToString:@"name"])
    {
        NSLog(@"赋值后--%@",self.hero.name);
        NSLog(@"新的值--%@",change[@"new"]);
        NSLog(@"以前的值--%@",change[@"old"]);

    }
}


回调打印如下:

201631795149534.png (211×54)


最后注销观察者

复制代码 代码如下:

- (void)dealloc{
    [self.hero removeObserver:self forKeyPath:@"name"];
}


到了这里观察者模式中常用的KVO及通知的内容就到这里,不过要知道这里谈及的只是最基础的用法,后面我们可能还是有更加深入的探究,或者在后续中可能还会对比iOS中的代理以及Block来探寻下iOS中的消息传递机制,再或者像Swift中的didSet、willSet的属性监听的方法,这些都是很好玩的内容,不是么?

    您感兴趣的教程

    在docker中安装mysql详解

    本篇文章主要介绍了在docker中安装mysql详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编...

    详解 安装 docker mysql

    win10中文输入法仅在桌面显示怎么办?

    win10中文输入法仅在桌面显示怎么办?

    win10系统使用搜狗,QQ输入法只有在显示桌面的时候才出来,在使用其他程序输入框里面却只能输入字母数字,win10中...

    win10 中文输入法

    一分钟掌握linux系统目录结构

    这篇文章主要介绍了linux系统目录结构,通过结构图和多张表格了解linux系统目录结构,感兴趣的小伙伴们可以参考一...

    结构 目录 系统 linux

    PHP程序员玩转Linux系列 Linux和Windows安装

    这篇文章主要为大家详细介绍了PHP程序员玩转Linux系列文章,Linux和Windows安装nginx教程,具有一定的参考价值,感兴趣...

    玩转 程序员 安装 系列 PHP

    win10怎么安装杜比音效Doby V4.1 win10安装杜

    第四代杜比®家庭影院®技术包含了一整套协同工作的技术,让PC 发出清晰的环绕声同时第四代杜比家庭影院技术...

    win10杜比音效

    纯CSS实现iOS风格打开关闭选择框功能

    这篇文章主要介绍了纯CSS实现iOS风格打开关闭选择框,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作...

    css ios c

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的办法

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的

    Win7给电脑C盘扩容的办法大家知道吗?当系统分区C盘空间不足时,就需要给它扩容了,如果不管,C盘没有足够的空间...

    Win7 C盘 扩容

    百度推广竞品词的投放策略

    SEM是基于关键词搜索的营销活动。作为推广人员,我们所做的工作,就是打理成千上万的关键词,关注它们的质量度...

    百度推广 竞品词

    Visual Studio Code(vscode) git的使用教程

    这篇文章主要介绍了详解Visual Studio Code(vscode) git的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...

    教程 Studio Visual Code git

    七牛云储存创始人分享七牛的创立故事与

    这篇文章主要介绍了七牛云储存创始人分享七牛的创立故事与对Go语言的应用,七牛选用Go语言这门新兴的编程语言进行...

    七牛 Go语言

    Win10预览版Mobile 10547即将发布 9月19日上午

    微软副总裁Gabriel Aul的Twitter透露了 Win10 Mobile预览版10536即将发布,他表示该版本已进入内部慢速版阶段,发布时间目...

    Win10 预览版

    HTML标签meta总结,HTML5 head meta 属性整理

    移动前端开发中添加一些webkit专属的HTML5头部标签,帮助浏览器更好解析HTML代码,更好地将移动web前端页面表现出来...

    移动端html5模拟长按事件的实现方法

    这篇文章主要介绍了移动端html5模拟长按事件的实现方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家...

    移动端 html5 长按

    HTML常用meta大全(推荐)

    这篇文章主要介绍了HTML常用meta大全(推荐),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参...

    cdr怎么把图片转换成位图? cdr图片转换为位图的教程

    cdr怎么把图片转换成位图? cdr图片转换为

    cdr怎么把图片转换成位图?cdr中插入的图片想要转换成位图,该怎么转换呢?下面我们就来看看cdr图片转换为位图的...

    cdr 图片 位图

    win10系统怎么录屏?win10系统自带录屏详细教程

    win10系统怎么录屏?win10系统自带录屏详细

    当我们是使用win10系统的时候,想要录制电脑上的画面,这时候有人会想到下个第三方软件,其实可以用电脑上的自带...

    win10 系统自带录屏 详细教程

    + 更多教程 +
    Windows系统Linux系统苹果MACAndroidiOS系统鸿蒙系统