oc实现kvo+block封装的观察者模式

引言

观察者模式能轻松实现对象间的消息传递和解耦,那么怎么方便的使用呢?所以我引入了block,oc的block类似于c语言的函数指针,非常灵活。

代码

建立一个类继承NSObject

PObject.h

//  PObject.h

#import 

extern NSString* const PObjectKeyPath;
extern NSString* const PObjectKeyPath2;

//定义block update
typedef void (^update)(NSObject* observable,NSObject* data);

@interface PObject : NSObject{
    NSObject* PObject;
    NSObject* PObject2;
}

/////////////////observerable////////////////////
//添加观察者
-(void)AddObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
//移除观察者
-(void)RemoveObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

/////////////////observer////////////////////////
//通知观察者更新
-(void)notifyObservers :(NSObject*)Value forKeyPath:(NSString *)keyPath;

-(void)update :(NSObject*)observable :(NSObject*)data;//继承重写的方式
@property(nonatomic) update blok;

-(instancetype)initWithBlock:(void (^)(NSObject* observable,NSObject* data))b;//作为observer不继承 需要实现的方法

@end

PObject.m

//  PObject.m

#import "PObject.h"
NSString* const PObjectKeyPath = @"PObject";
NSString* const PObjectKeyPath2 = @"PObject2";

@implementation PObject

-(instancetype)initWithBlock:(update)b{
    self = [super init];
    if (self) {
        self.blok = b;
    }
    return self;
}

//添加观察者
-(void)AddObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath{
    if (keyPath == nil) {
        [self addObserver:observer forKeyPath:PObjectKeyPath options:NSKeyValueObservingOptionNew context:nil];
    }else{
        [self addObserver:observer forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:nil];
    }
    
}
//移除观察者
-(void)RemoveObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath{
    if (keyPath == nil) {
        [self removeObserver:observer forKeyPath:PObjectKeyPath];
    }else{
        [self removeObserver:observer forKeyPath:keyPath];
    }
}

//通知观察者更新
-(void)notifyObservers :(NSObject*)Value forKeyPath:(NSString *)keyPath
{
    if (keyPath == nil) {
        [self setValue:Value forKey:PObjectKeyPath];
    }else{
        [self setValue:Value forKey:keyPath];
    }
    
}

//观察者更新
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    [self update:object :[change valueForKeyPath:NSKeyValueChangeNewKey]];
}

-(void)update :(NSObject*)observable :(NSObject*)data
{
    if (self.blok) {
        self.blok(observable,data);
    }
}
@end

示例

#import "PObject.h"
NSObject * mObservable;//任意一个oc对象
PObject *mObserver;
//初始化观察者
mObserver = [[PObject alloc]initWithBlock:^(NSObject *observable, NSObject *data) {
        //操作observable传过来的数据data
}];
//添加观察者
[mObservable AddObserver: mObserver];
//通知观察者更新
[mObservable notifyObservers:@"data" forKeyPath:nil];
//移除观察者
[mObservable RemoveObserver:mObserver forKeyPath:nil];

2018.9.5

你可能感兴趣的:(oc实现kvo+block封装的观察者模式)