服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - iOS应用开发中使用设计模式中的观察者模式的实例

iOS应用开发中使用设计模式中的观察者模式的实例

2021-01-10 15:06晓风沐晨 IOS

这篇文章主要介绍了iOS应用开发中使用设计模式中的观察者模式的实例,包括Cocoa框架使用中的KVO机制的相关配合运用,代码为传统的Objective-C,需要的朋友可以参考下

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

iOS应用开发中使用设计模式中的观察者模式的实例

 


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

iOS应用开发中使用设计模式中的观察者模式的实例

通过上面的观察我们可以发现如果用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"]);

 

    }
}


回调打印如下:

 

iOS应用开发中使用设计模式中的观察者模式的实例


最后注销观察者

 

复制代码 代码如下:


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

 

 


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

延伸 · 阅读

精彩推荐
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28