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.二 ...
随机推荐
- android 选项卡TabHost
选项卡主要有TabHost.TabWiget和 FramentLayout3个组件组成,用于实现一个多标签的用户界面,通过他可以将一个复杂的对话分隔成若干个标签页,实现对信息的分类显示和管理.使用给组 ...
- 从一个简洁的进度刻度绘制中了解自定义View的思路流程
先看效果(原谅我的渣像素),进度的刻度.宽度.颜色可以随意设定: [项目github地址: https://github.com/zhangke3016/CircleLoading] 实现起来并不难, ...
- 软考下午题详解---uml图
在上篇博客中,小编主要简单的对软考下午题当中的数据流图设计进行了一系列总结,今天我们继续来看软考下午题当中大题部分,uml图的相关知识,在我们学习的过程中,我们也已经接触过,西安交大刘惠老师讲解过um ...
- (NO.00005)iOS实现炸弹人游戏(七):游戏数据的序列化表示
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 用plist列表文件来表示游戏数据 因为在这个炸弹人游戏中有很多 ...
- SIMPLE_DEV_PM_OPS宏
SYSTEM_SLEEP_PM_OPS和dev_pm_ops的定义: [cpp] view plain copy #define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, ...
- 定制Maven原型生成项目
1自定义原型 1.1创建原型项目 要定制自己的原型,首先就要创建原型项目来进行定制: mvnarchetype:create -DgroupId=com.cdai.arche -DartifactId ...
- 【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)
作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42462795 转载请著名出处 相关资源下载 : -- u-boo ...
- 【Unity Shaders】Transparency —— 透明的cutoff shader
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- Dynamics CRM2013 去除界面顶部黄色的CRM For Outlook条框
Dynamics CRM2013中每次打开系统页面上方都会有个黄条看着很是烦人,效果如下图 庆幸的是系统提供了关闭的开关,设置-管理-系统设置,把"设置CRM For Outlook消息是否 ...
- Linux IPC实践(8) --共享内存/内存映射
概述 共享内存区是最快的IPC形式.一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据(如图). 共享内存 VS ...