obj-c编程18:多对多的观察者模式
我们知道使用委托的设计模式可以实现一对一的通知关系,但是如果需要通知多个观察者状态变化又该如何呢?此时,需要实现观察者模式之类的内容,而不是实现委托者一对一的模式。
观察者模式定义了一个对象可以将另一个对象注册成自身观察者的模式,对象被注册成观察者后,任何观察者关注者事件都会在其发生时send给观察者。obj-c中实现观察者模式是通过NSNotificationCenter类实现的。该类为观察者对象和事件提供了一个全局调度系统。观察者可以向其注册观测系统中特定的事件;而被观察对象,在事件发生时,也可以发布通知到NSNotificationCenter,这样任何被观察者对象的通知可以发送到任何观察者对象,从而达到多对多关系的观察者模式。
为了完成观察者模式,一般要完成以下几个步骤:
1: 观察者使用NSNotificationCenter实例方法-addObserver将自身注册为特定事件的观察者;
2: 观察者要实现步骤1中注册的回调方法;
3: 被观察者对象要使用-postNotifiationName之类的发送方法发送消息;
4: 观察者最终要确保在释放时使用-removeObserver:将自己从NSNotificationCenter中移除。
下面用杜撰的代码来看看实际如何实现观察者模式。代码中狗仔队对于明星无聊中的对话可谓是八卦之极,star的每一句话都要设法得到啊。不过从实际代码看来,貌似明星也有意的想把这些对话内容传播出去啊!如果不想,那就类似于<<obj-c编程17:键值观察>>里的键值观察模式了哦。下面上代码:
#import <Foundation/Foundation.h>
#define msg(...) NSLog(__VA_ARGS__)
#define NOTIFICATION_NAME @"MY_NOTIFICATION"
@interface Star:NSObject{
NSString *name;
}
@property(readonly) NSString *name;
-(void)talk:(NSString *)blabla;
@end
@implementation Star
@synthesize name;
-(id)initWithName:(NSString *)name_v{
self = [super init];
if(self){
name = name_v;
}
return self;
}
-(void)talk:(NSString *)blabla{
msg(@"%@ to say :%@",name,blabla);
NSDictionary *secret = [NSDictionary dictionaryWithObject:blabla \
forKey:@"words"];
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_NAME \
object:self userInfo:secret];
}
@end
@interface Dog:NSObject
-(void)broadcast:(NSNotification *)note;
@end
@implementation Dog
-(id)init{
self = [super init];
if(self){
[[NSNotificationCenter defaultCenter] addObserver:self \
selector:@selector(broadcast:) name:NOTIFICATION_NAME \
object:nil];
}
return self;
}
-(void)broadcast:(NSNotification *)note{
NSString *star_name = [[note object] name];
NSString *words = [[note userInfo] objectForKey:@"words"];
msg(@"star %@ sayed \"%@\"",star_name,words);
}
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
//[super dealloc];
}
@end
int main(int argc,char *argv[])
{
@autoreleasepool{
Star *star0 = [[Star alloc] initWithName:@"lucy"];
Star *star1 = [[Star alloc] initWithName:@"jack"];
Dog *dog = [[Dog alloc] init];
[star0 talk:@"no shit!"];
[star1 talk:@"that's right!"];
}
return 0;
}
运行结果是我们可以预料到的:
apple@kissAir: objc_src$./9
2014-08-03 21:05:11.830 9[910:507] lucy to say :no shit!
2014-08-03 21:05:11.831 9[910:507] star lucy sayed "no shit!"
2014-08-03 21:05:11.832 9[910:507] jack to say :that's right!
2014-08-03 21:05:11.832 9[910:507] star jack sayed "that's right!"
有人会说了,你这是1对多关系哦。多对多关系也很简单,狗仔队不止一只啊,我们再来创建1个,改变的代码如下:
int main(int argc,char *argv[])
{
@autoreleasepool{
Star *star0 = [[Star alloc] initWithName:@"lucy"];
Star *star1 = [[Star alloc] initWithName:@"jack"];
Dog *dog0 = [[Dog alloc] init];
Dog *dog1 = [[Dog alloc] init];
[star0 talk:@"no shit!"];
[star1 talk:@"that's right!"];
}
return 0;
}
运行结果如下:
apple@kissAir: objc_src$./9
2014-08-03 21:32:43.513 9[973:507] lucy to say :no shit!
2014-08-03 21:32:43.514 9[973:507] star lucy sayed "no shit!"
2014-08-03 21:32:43.515 9[973:507] star lucy sayed "no shit!"
2014-08-03 21:32:43.515 9[973:507] jack to say :that's right!
2014-08-03 21:32:43.516 9[973:507] star jack sayed "that's right!"
2014-08-03 21:32:43.516 9[973:507] star jack sayed "that's right!"
obj-c编程18:多对多的观察者模式的更多相关文章
- pta编程(1-8)
知识点:本次编程运用到的格式 #include<stdio.h> int main(void) { printf(); return 0; } 过程:1-3.没什么问题,就是注意字符的输入 ...
- Win64 驱动内核编程-18.SSDT
SSDT 学习资料:http://blog.csdn.net/zfdyq0/article/details/26515019 学习资料:WIN64内核编程基础 胡文亮 SSDT(系统服务描述表),刚开 ...
- Qt编程18:Qt调色板QPalette的使用
QPalette类有两个枚举类型, 枚举 1.ColorGroup CorGroup指的是3中不同的状态(什么时候设置颜色): 1>Active:获得焦点的状态. 2>Inactive:未 ...
- Linux编程 18 安装软件程序(yum工具对软件包安装,删除,更新介绍)
一. 概述 本篇介绍在linux上见到的各种包管理系统(package management system,PMS)用来进行软件安装,管理,删除的命令行工具.PMS是利用一个数据库来记录各种相关内 ...
- Java Swing界面编程(18)---单行文本输入组件:JTextField
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/xuejiawei123/article/details/27565407 下面的程序与上一例有一点差 ...
- python面向对象编程(下)
本篇详细介绍了Python 中类的成员.成员修饰符.类的特殊成员以及两个综合运用实例. 环境为:python3.5.1 类的成员 类的成员包括三大类:字段.方法和property属性 注:关于这三类成 ...
- Python面向对象进阶和socket网络编程-day08
写在前面 上课第八天,打卡: 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __i ...
- django(八)之数据库表的一对多,多对多表-增删改查
单表操作 表记录的添加 方式一: Book() b=Book(name="python基础",price=99,author="yuan",pub_date=& ...
- python自动化开发-[第八天]-面向对象高级篇与网络编程
今日概要: 一.面向对象进阶 1.isinstance(obj,cls)和issubclass(sub,super) 2.__setattr__,__getattr__,__delattr__ 3.二 ...
随机推荐
- FFmpeg源代码简单分析:日志输出系统(av_log()等)
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- 18 Ui美化
资源文件的使用: 一: res中文件中放置的文件类型: res/drawable//放处理过的图片 res/drawable-XXX //放的Ui切得图 >res/anim 放动画 >re ...
- Java基础---Java---IO流-----File 类、递归、删除一个带内容的目录、列出指定目录下文件夹、FilenameFilte
File 类 用来将文件或者文件夹封装成对象 方便对文件与文件夹进行操作. File对象可以作为参数传递给流的构造函数 流只用操作数据,而封装数据的文件只能用File类 File类常见方法: 1.创建 ...
- Oracle中使用游标转换数据表中指定字段内容格式(拼音转数字)
应用场景:将数据表TB_USER中字段NNDP的内容中为[sannanyinv]转换为[3男1女] 主要脚本:一个游标脚本+分割字符串函数+拼音转数字脚本 操作步骤如下: 1.创建类型 create ...
- 最简单的基于FFmpeg的解码器-纯净版(不包含libavformat)
===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...
- UNIX网络编程——线程池模式比较(ICE线程池模型和L/F领导者跟随者模式)
程池模式一般分为两种:L/F领导者与跟随者模式.HS/HA半同步/半异步模式. HS/HA 半同步/ 半异步模式 :分为三层,同步层.队列层.异步层,又称为生产者消费者模式,主线程处理I/O事件并解析 ...
- Java-IO之FilterInputStream和FilterOuptStream
FilterInputStream的作用是用来封装其他的输入流,并为它们提供了额外的功能,它的常用的子类有BufferedInputStream和DataInputStream.FilterOutpu ...
- Dynamics CRM 导入用户数据错误 could not retrieve salesperson role
在CRM中通过导入数据的方式创建用户时报下图中的错误,"could not retrieve saleperson role".原因是系统中的自带的salesperson安全角色被 ...
- mixer: mysql协议分析
综述 要实现一个mysql proxy,首先需要做的就是理解并实现mysql通讯协议.这样才能通过proxy架起client到server之间的桥梁. mixer的mysql协议实现主要参考mysql ...
- jenkin插件整理
分类 plugin名称 wiki地址 源码地址 plugin作用范围 备注 Build Reports构建报告(此类插件用来分析构建结果,比果代码检查,测试CASE分析,并将这些结果以报表,趋势图等形 ...