iOS常用设计模式——观察者设计模式

来源:互联网 发布:西安市行知中学好不好 编辑:程序博客网 时间:2024/06/05 03:50

观察者设计模式详解

  • 观察者设计模式详解
    • 基本概念
    • NSNotificationCenter的使用
      • 添加监听
      • 接收消息
      • 删除监视
    • KVO的使用
      • 基本概念
      • 注册观察者
      • 观察者对象发生变化时的回调方法
      • remove观察者身份
      • 代码实现

基本概念

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己.而在IOS开发中我们可能会接触到的经典观察者模式的实现方式,有这么几种:NSNotificationCenter、KVO、Delegate等

NSNotificationCenter的使用

添加监听

  • (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;
    sample:
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSomething:) name:GET_UP object:nil];
    说明:
    【NSNotificationCenter defaultCenter】消息中心只有一个,通过该方法获取该类的单例
    addObserver:添加监听者
    selector:表示监听到到对象后的处理函数
    name:表示注册所关心的消息名称

接收消息

  • (void)postNotification:(NSNotification *)notification;
  • (void)postNotificationName:(NSString *)aName object:(id)anObject;
  • (void)postNotificationName:(NSString )aName object:(id)anObject userInfo:(NSDictionary )aUserInfo;
    sample:
    [[NSNotificationCenter defaultCenter] postNotificationName:GET_UP object:[NSNumber numberWithInteger:self.time]];
    分析:
    GET_UP:推送消息的名称
    object:发送消息的对象
    userInfo:发送消息携带的信息

删除监视

  • (void)removeObserver:(id)observer;
  • (void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;

KVO的使用

基本概念

KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。该方法与NSNotification有很大的不同,它并不需要一个NotificationCenter来为所有观察者提供变化通知,相反的是,当有变化发生时,该通知直接发送给观察者,NSObject为我们实现了此方法。
利用此方法我们可以观察对象,是一种一对多的关系。

注册观察者

首先必须发送一个
addObserver:selfforKeyPath:@”happyNum” options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld
context:nil]消息至观察对象,用以传送观察对象和需要观察的属性的关键路径,参数分析:
- (void)addObserver:(NSObject )observer forKeyPath:(NSString )keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
observer:表示观察者是谁,一般为self
keyPath: 表示观察哪个对象
options:NSKeyValueObservingOptionNew表示观察新值,NSKeyValueObservingOptionOld表示观察旧值
context:表示上下文环境

观察者对象发生变化时的回调方法

  • (void)observeValueForKeyPath:(NSString *)keyPath
    ofObject:(id)object
    change:(NSDictionary *)change
    context:(void *)context {

    NSLog(@”%@”,change);
    }
    参数分析:
    change:表示发生改变时返回的值
    keyPath:表示观察对象
    contenst:表示上下文

remove观察者身份

发送一条制定观察方对象和路径来移除观察者,该函数一般放在dealloc:
[self.childremoveObserver:selfforKeyPath:@”happyNum”context:nil];

代码实现

child.h#import <Foundation/Foundation.h>@interface Child : NSObject@property(nonatomic,assign)NSInteger happyNum;@endchild.m#import "Child.h"@implementation Child-(id)init{    self=[super init];    if(self)    {        self.happyNum=100;        [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(decrease:) userInfo:nil repeats:YES];    }    return  self;}-(void)decrease:(NSTimer*)timer{  // NSLog(@"the happyNum is %ld",self.happyNum);    _happyNum--;   // [self setValue:[NSNumber numberWithInteger:_happyNum] forKey:@"happyNum"];}@endnurse.h#import <Foundation/Foundation.h>#import "Child.h"@interface Nurse : NSObject@property(nonatomic,retain)Child *child;-(id)initWithChild:(Child*)child;@endnurse.m:#import "Nurse.h"@implementation Nurse-(id)initWithChild:(Child*)child{    self=[super init];    if(self)    {        self.child = child;        [self.child addObserver:self forKeyPath:@"happyNum"                    options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld                    context:nil];    }    return  self;}- (void)observeValueForKeyPath:(NSString *)keyPath                      ofObject:(id)object                        change:(NSDictionary *)change                       context:(void *)context {    NSLog(@"%@",change);}-(void)dealloc{    [self.child removeObserver:self forKeyPath:@"happyNum" context:nil];    [_child release];    [super dealloc];}@endmain.m:#import <Foundation/Foundation.h>#import "Child.h"#import "Nurse.h"int main(int argc, const char * argv[]){    @autoreleasepool {        Child *childObj=[[[Child alloc] init] autorelease];        Nurse *nurseObj=[[[Nurse alloc] initWithChild:childObj] autorelease];        [[NSRunLoop currentRunLoop] run];        //[nurseObj release];    }    return 0;}
0 0
原创粉丝点击