设计模式IOS篇-第三章:观察者模式

观察者模式在IOS中也是总要的一种模式,被观察的对象会告诉观察它的对象发生的一些变化,这里会分为两个实现类和两个接口

下面的一个Subject类,包含两个委托ObjectDelagate和SubjectDelegate

//Subject.h
#import <Foundation/Foundation.h>

//观察者委托
@protocol ObserverDelegate

@required
-(void)update;

@end

//被观察者委托
@protocol SubjectDelegate

@required
-(void)addObserver:(id<ObserverDelegate>)observer;
-(void)removeObservers:(id<ObserverDelegate>)observer;


@end



@interface Subject : NSObject<SubjectDelegate>

+(Subject *)shareManager;


@end


//Subject.m
#import "Subject.h"

@interface Subject()
@property(weak,nonatomic)NSMutableArray *observers;
@end

@implementation Subject

static Subject *subject = nil;

+(Subject *)shareManager
{
    static dispatch_once_t one;
    dispatch_once(&one,^{
        subject = [[Subject alloc]init];
    });
    
    return subject;
}

-(void)addObserver:(id<ObserverDelegate>)observer
{
    [self.observers addObject:observer];
}

-(void)removeObservers:(id<ObserverDelegate>)observer
{
    [self.observers removeObject:observer];
}

@end

下面的是Observer类

//Observer.h
#import <Foundation/Foundation.h>
#import "Subject.h"

@interface Oberver : NSObject<ObserverDelegate>

@end

//Observer.m
#import "Oberver.h"

@implementation Oberver

-(id)init
{
    self = [super init];
    if(self)
    {
        //获取到Subject的单例,然后进行观察(加入到被观察者中,如果有变化,会调用观察者的update方法)
        [[Subject shareManager]addObserver:self];
    }
    return self;
}

-(void)update
{
    
}

@end

在IOS中,有两个这样的机制是实现了观察者模式,通知(notification)机制和KVO(Key-Value Observing) 机制,下面简要介绍这两种机制。

通知机制

通知机制最主要的类是NSNotificationCenter,是单列模式。获取它的单列是[NSNotificationCenter defaultCenter],addObserver是添加观察者对象,selector是接收到通知时处理的方法,name是等待何种命令,object是接收到的数据。在下面的例子中的意思是,把自己当前的类(self)作为观察者,当某地发出"AppWillTerminateNotification"的通知的时候由观察者(self)中的handleTerminate的方法去处理接收到的通知。

[[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(handleTerminate:)
            name:@"AppWillTerminateNotification"
            object:nil];

下面这个是发出通知的方法,postNotificationName是发出通知的名字,object是发出通知的对象,userInfo是发出通知附带的字典,通常用于传递参数

//传参的字典
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
[dict setValue:@"Hello" forKey:@"TalkToYou"];
        
//发出的通知,发出名字为AppNotification的通知
[[NSNotificationCenter defaultCenter]postNotificationName:@"AppNotification" object:self userInfo:dict];
//下面这种是可以不带userInfo的
[[NSNotificationCenter defaultCenter]postNotificationName:@"AppNotification" object:self];

在通知到的对象里面,需要实现通知到的时候实现的方法(这个方法名字是在添加观察者的时候定义的)可以从里面获取到传递的参数

-(void)action:(NSNotification *)note
{
    NSDictionary *dict = [note userInfo];
    if (dict != nil) {
        [dict objectForKey:@"Hello"];
    }
    
}

KVO机制

KVO机制跟通知机制有点不一样,KVO机制是当对象的某个属性更改时,直接通知观察者成员

先来看看被观察者需要写的代码部分,addObserver这里先要获取到一个观察者的对象,forKeyPath就是被观察对象的一个key,options属性变化的选项,context就是上下文,以下这句代码的意思是,被观察者通知Observer对象类,我的其中一个属性,key为"appStatus"被更改了

Observer *observer= [Observer new];
[self addObserver:subject forKeyPath:@"appStatus" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"Pass Context"];

当发出了通知之后,观察者类会收到通知,执行一下的方法,这个方法不需要继承任何的委托,继承至NSObject的所有类都会自动继承了一下的这个方法,这个方法中,keyPath就是属性的Key,ofObject就是被观察者对象,change就是一个传递的值的数据字典,context就是传递的上下文

- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object
    change:(NSDictionary*)change context:(void*)context
{
    NSLog(@"Property '%@' of object '%@' changed: %@context: %@",keyPath,object,change,context);
}
原文地址:https://www.cnblogs.com/oscar1987121/p/5238992.html