觀察者模式⼜又被稱做發佈/訂閱模式程序員
觀察者模式定義了一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並自動更新;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];