[非法程序員]Object-c觀察者模式

觀察者模式⼜又被稱做發佈/訂閱模式程序員

觀察者模式定義了一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並自動更新;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[]) {

    @autoreleasepool {

        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];

相關文章
相關標籤/搜索