美文网首页iOS 进阶iOS开发
oc实现kvo+block封装的观察者模式

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

作者: 红树_ | 来源:发表于2018-09-05 10:53 被阅读210次

    引言

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

    代码

    建立一个类继承NSObject

    PObject.h

    //  PObject.h
    
    #import <Foundation/Foundation.h>
    
    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<NSKeyValueChangeKey,id> *)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封装的观察者模式

        本文链接:https://www.haomeiwen.com/subject/gcoowftx.html