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.二 ...
随机推荐
- 剑指Offer——简述堆和栈的区别
剑指Offer--简述堆和栈的区别 堆(Heap) Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建: Java虚拟机规范描述:所有的对象实例及数组都要在堆上分配: Java堆可以处于物理 ...
- Swift基础语法(常量变量、数据类型、元组、可选、断言)
本文来自Swift中文开发组,感谢翻译者的分享. 本文将分几部分对Swift对ios的语法做讲解.本文为第一节,主要讲解基础语法. 常量和变量 常量和变量把一个名字(比如maximumNumberOf ...
- 15 ActionBar 总结
ActionBar 一, 说明 是一个动作栏 是窗口特性 提供给用户动作 导航模式 可以适配不同的屏幕 二, ActionBar 提供的功能 1. 显示菜单项 always:总是展示到ActionBa ...
- hadoop端口使用配置总结(非常好的总结)
转自http://www.aboutyun.com/thread-7513-1-1.html Hadoop集群的各部分一般都会使用到多个端口,有些是daemon之间进行交互之用,有些是用于RPC访问以 ...
- 【Shader拓展】Illustrative Rendering in Team Fortress 2
写在前面 早在使用ramp texture控制diffuse光照一文就提到了这篇著名的论文.Valve公司发表的其他成果可见这里.这是Valve在2007年发表的一篇非常具有影响力的文章,我的导师也提 ...
- UNIX网络编程——基本TCP套接字编程
一.基于TCP协议的网络程序 下图是基于TCP协议的客户端/服务器程序的一般流程: 服务器调用socket().bind().listen()完成初始化后,调用accept()阻塞等待,处于监听端口的 ...
- pyinstaller使用-python项目转换成exe可执行文件
http://blog.csdn.net/pipisorry/article/details/50620122 Python不是每个人的计算机里面都有安装,当您写了一个好用的工具,需要一个standa ...
- ROS_Kinetic_07 ROS中机器人三维物理引擎高保真仿真利器gazebo 7.0
ROS_Kinetic_07 ROS中机器人三维物理引擎高保真仿真利器gazebo 7.0 ROS kinetic中的gazebo版本是7.0,有很多新的特性. 首先,启动gazebo: ~$ gaz ...
- ROS(indigo)机器人操作系统学习有趣丰富的Gazebo仿真示例evarobot
一直在寻找一个示例可以将ROS学习中常用的基础内容大部分都包含进去,最好还包括Gazebo仿真, 这样即使没有硬件设备,也可以很好的学习ROS相关内容,但又必须有对应的硬件,便于后续研究. 这里,介绍 ...
- iOS中 读取相册,调用系统相机 技术分享
技术内容:分别读取相册以及调取相机,将图片显示到imageView上 布局: 1.创建imageView 和 button 并为button一个关联pickerImage的事件 <div sty ...