观察者模式⼜又被称做发布/订阅模式程序员
观察者模式定义了一种一对多的依赖关系,当一个对象的状态发生改变时,全部依赖于它的对象都获得通知并自动更新;post
观察者模式的结构中包括四种角色:主题(Subject) 观察者 (Observer) 具体主题(ConcreteSubject)具体观察者(ConcreteObserver)atom
观察者模式主要有两种获取数据的方式 spa
推:主题把变化后的数据所有交给观察者 .net
拉: 观察者本身经过主题提供的得到数据的方法把数据拉过来 3d
何时使用对应的方式:orm
观察者须要变换后的所有数据时可采用 推数据方式 推在IOS中典型的实现方式为:NSNotificationCenter (通知中心只能通知,并不能知道属性值变化前和变化后的值)和KVO(能够得到属性值变化前和变化后的值)server
主题不知道观察者是否须要变换后的数据时可采用 拉数据方式对象
优势:内存
具体主题和具体观察者是松耦合关系
观察者模式知足“开-闭原则”。
缺点:1.观察者多了,都通知到会花费必定时间
2.若是在被观察者之间有循环依赖的话,观察者会触发
它们之间进行循环调用,致使系统崩溃。进入死循环。
3.观察者模式只能知道对象发生了变化(获得结果),可是不知道如何发生变化的(没有变化过程 )。
观察者的实现过程 :注册——通知——撤销注册
注册:注册(某个对象 student) + 接收的方法(@select(自定义方法名))
关键字 NSNotificationCenter 通知中心 defaultCenter 这是一个类方法 addObserver 添加观察者 postNotificationName 通知的名称
#import <Foundation/Foundation.h>
#import "Student.h"
#import "Goods.h"
int main(int argc, const char * argv[]) {
Student *stu=[[Student alloc]init];
stu.name=@"Student_one";
//----------- 通知 --------------
//通知步骤: 注册/接收 --> 通知 --> 移除
//注册(某个对象 student) + 接收的方法(@select(自定义方法名))
//注意:每当写入注册对象,请在注册对象里写上接收方法。
//参数说明:addObserver: 观察者 selector:@select(接收方法)
//接收方法最好加冒号,为了参数传参数。name: 通知名称 object:通知发送人 可为nil
[[NSNotificationCenter defaultCenter] addObserver:stu selector:@selector(backChangeMessage:) name:@"notificationStudent" object:nil];
//通知方法 通常为发送通知消息
//注意:通知名称必须为已注册的通知名称,发送的通知可为任意对象类型
//参数说明:postNotificationName: 通知名称 objects: 被发送消息
[[NSNotificationCenter defaultCenter] postNotificationName:@"notificationStudent" object:stu];
//----- 拉模型 可用delegate实现 -----
//拉模型: 由商品给出更改消息,仅仅是消息,由Person主动去拉取Goods信息
//Goods -> setPrice 经过更改price值,回调通知消息给Person类, Person主动去拉去值
Goods *good=[[Goods alloc]init];
good.price=12;
Student *xiaoMing=[[Student alloc]init];
xiaoMing.name=@"XiaoMing";
xiaoMing.goods=good;
good.stu=xiaoMing;
[[NSNotificationCenter defaultCenter] addObserver:xiaoMing selector:@selector(backMessage:) name:@"goodsNotification" object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"goodsNotification" object:good];
good.price=22;
//
// Goods.h
// 观察者模式
//
// Created by 非凡 程序员 on 15/11/6.
// Copyright (c) 2015年 非凡 程序员. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "goodsProtocol.h"
#import "Student.h"
@interface Goods : NSObject<myProtocol>
@property(nonatomic,strong)id<myProtocol> stu;
@end
//
// Goods.m
// 观察者模式
//
// Created by 非凡 程序员 on 15/11/6.
// Copyright (c) 2015年 非凡 程序员. All rights reserved.
//
#import "Goods.h"
@implementation Goods
@synthesize price=_price;
-(void)setPrice:(float)price{
_price=price;
[_stu changeMethod];
}
@end
//
// goodsProtocol.h
// 观察者模式
//
// Created by 非凡 程序员 on 15/11/6.
// Copyright (c) 2015年 非凡 程序员. All rights reserved.
//
@protocol myProtocol <NSObject>
@optional
@property(nonatomic,assign)float price;
-(void)changeMethod;
@end
//
// Student.h
// 观察者模式
//
// Created by 非凡 程序员 on 15/11/6.
// Copyright (c) 2015年 非凡 程序员. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "goodsProtocol.h"
@class Goods;
@interface Student : NSObject<myProtocol>
@property(nonatomic,strong)NSString *name;
@property(nonatomic,weak)id<myProtocol> goods;
-(void)backChangeMessage:(NSNotification *)notifacation;
-(void)backMessage:(NSNotification *)goodsNotification;
@end
//
// Student.m
// 观察者模式
//
// Created by 非凡 程序员 on 15/11/6.
// Copyright (c) 2015年 非凡 程序员. All rights reserved.
//
#import "Student.h"
@implementation Student
-(void)changeMethod{
NSLog(@"changeMethod ...");
NSLog(@"%f",_goods.price);
}
-(void)backChangeMessage:(NSNotification *)notifacation{
Student *student=notifacation.object;
NSLog(@"name:%@",student.name);
}
-(void)backMessage:(NSNotification *)goodsNotification{
NSLog(@"%@",goodsNotification.object);
// _goods=goodsNotification.object;
// [_goods ]
}
-(void)dealloc{
//移除 防止内存泄漏
//方法说明: removeObserver: 观察者 name: 通知名称 object 发送人 该方法为移除观察者的消息通知
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"notificationStudent" object:nil];
//方法说明: removeObserver: 观察者 该方法为移除观察者对象
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"goodsNotification" object:nil];
//方法说明: removeObserver: 观察者 该方法为移除观察者对象
[[NSNotificationCenter defaultCenter] removeObserver:_goods];