iOS设计模式之观察者模式
2015-08-06 10:33
337 查看
观察者模式
基本理解
观察者模式又叫做发布-订阅(Publish/Subscribe)模式。观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,是他们能够自动更新自己。
观察者只从通知器(发行商)把自己注册到(订阅)特定的通知(杂志)。当有通知的时候,观察者从通知器得到它订阅的通知。
观察者模式的特点
将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维护一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。而观察者的关键是有一个对象(Model),它可以有多个观察者,一旦对象的状态发生了变化,那么所有的观察者都可以得到通知,及时更新。
使用场景
当一个对象的改变需要同时改变其他对象的时候,我们就可以使用,而且不知道具体有多少个对象有待改变时,应该考虑使用观察者模式。观察者模式所做的工作就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。
例如,当用户点击视图上的排序按钮时,事件会传递给控制器,让模型在后台对其数据进行排序。当模型成功执行了对数据的操作后,它会通知所有相关的控制器,让他们用到的数据更新其视图。
在Cocoa Touch框架中使用观察者模式
Cocoa Touch框架用两种技术改写了观察者模式--通知和键值观察(KVO)。尽管是两种不同的Cocoa技术,两者都实现了观察者模式。通知
Cocoa Touch框架中使用NSNotificationCenter和NSNotification对象实现了一对多的发布订阅模型。一个中心对象为所有观察者提供变更通知,主要从广义上关注程序事件
键值观察
被观察的对象直接向观察者发送通知,绑定与特定对象属性的值。
例子
User.h// // User.h // ObserverDemo // // Created by zhanggui on 15/8/6. // Copyright (c) 2015年 zhanggui. All rights reserved. // #import <Foundation/Foundation.h> @interface User : NSObject { NSString *userName; NSString *userAge; NSString *userAddress; } @end
User.m
// // User.m // ObserverDemo // // Created by zhanggui on 15/8/6. // Copyright (c) 2015年 zhanggui. All rights reserved. // #import "User.h" @implementation User @end
ViewController.m
// // ViewController.m // ObserverDemo // // Created by zhanggui on 15/8/6. // Copyright (c) 2015年 zhanggui. All rights reserved. // #import "ViewController.h" #import "User.h" @interface ViewController () { User *user1; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; user1 = [User new]; [user1 setValue:@"zhangsan" forKey:@"userName"]; //KVO [user1 addObserver:self forKeyPath:@"userName" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:@"I want to update name"]; _nameLabel.text = [user1 valueForKey:@"userName"]; //Notification [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeColor:) name:@"changeColor" object:nil]; } -(void)dealloc { [user1 removeObserver:self forKeyPath:@"userName"]; } #pragma mark - NotificationAction -(void)changeColor:(NSNotification *)notification { if ([notification.object isKindOfClass:[UIColor class]]) { self.view.backgroundColor = (UIColor *)notification.object; } NSLog(@"我收到通知了"); } #pragma mark - ButtonAction - (IBAction)buttonAction:(id)sender { [user1 setValue:@"zhangqiang" forKey:@"userName"]; } #pragma mark - ObserverMehtod -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@"userName"]) { _nameLabel.text = [user1 valueForKey:@"userName"]; } } @end
SecondViewController.m
// // SecondViewController.m // ObserverDemo // // Created by zhanggui on 15/8/6. // Copyright (c) 2015年 zhanggui. All rights reserved. // #import "SecondViewController.h" @interface SecondViewController () @end @implementation SecondViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. } - (IBAction)changeColorAction:(id)sender { [[NSNotificationCenter defaultCenter] postNotificationName:@"changeColor" object:[UIColor redColor]]; } @end
上述例子中分别使用了KVO和NSNotificationCenter来体现观察者模式。其中:
[user1 addObserver:self forKeyPath:@"userName" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:@"I want to update name"];
我们给user1添加观察者self,也就是ViewController。让它去观察user的userName属性,当有更新的时候就会调用:
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@"userName"]) { _nameLabel.text = [user1 valueForKey:@"userName"]; } }
在这里来处理显示内容的更新。
还有就是通过SecondViewController中点击一个按钮去改变ViewController的背景色,具体请看代码。
附:
源码下载地址:http://pan.baidu.com/s/1hq706hu相关文章推荐
- iOS之引导页开发(一)——采用NSUserDefaults进行首次运行判断
- iOS :undefined symbols for architecture x86_64
- iOS中的沙盒机制
- iOS如何把导航默认的返回按钮设置成“返回”
- iOS8新特性扩展(Extension)应用之一——Today扩展
- 提高iOS开发效率的方法和工具
- iOS开发:开发中如何更改项目名
- ios页面间传递参数四种方式
- [iOS]常用正则表达式
- IOS开发-四种保存数据的方式
- iOS设计模式之组合模式
- Xamarin.iOS,AOT,JIT,Limitations
- [autoLayout]自动布局下的纯storyboard添加约束--四个imageView平分一个屏幕的宽度
- ios 键盘最底行文字遮挡
- iOS NSDate与NSString之间的相互转换
- iOS-真机调试
- iOS-设置启动图片
- iOS中—触摸事件详解及使用
- iOS 9应用开发教程之创建iOS 9项目与模拟器介绍
- IOS开发他山之石系列-安装Alcatraz