iOS学习心得之:KVO

作者: 人话博客 | 来源:发表于2017-04-30 12:32 被阅读11次

    KVO 是 key/value/observing 的缩写
    个人理解的意思是:当对应的key的值value发生改变时,通知observer观察者执行一些操作.

    基本就是一个观察者模式,和事件模型一模一样.

    // 当前事件发布者是 ChangeMyProperty对象
    // 当前的事件订阅者是 MyObserverObj对象.
    //
    //先浅显的解释一下啥是KVO.
        //KVO = key / value / observing.
        //当被被观察者的某个属性发生变化的时候,会通知观察者执行一些事情.
        
        ChangeMyProperty *cp = [[ChangeMyProperty alloc] init];
        //定义观察者
        MyObserverClass *mc = [[MyObserverClass alloc] init];
        //注册观察者
        //当cp的name属性调用setter方法,就会通知mc对象处理相关操作.
        [cp addObserver:mc forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
        
        cp.name = @"张三";
        
        [cp removeObserver:mc forKeyPath:@"name"];
    

    属性发生改变时的事件响应方法.

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
    {
        NSLog(@"被监控的属性是:%@",keyPath);
        NSLog(@"被监控的对象类型是:%@",[object className]);
        
        NSLog(@"值放生了变化啦!!!");
    }
    
    

    最终结果:

    KVO事件响应函数输出的结果

    可以看出:
    第一个参数是[被监控对象的属性].
    第二个参数是[被监控对象的类型].
    也就是所谓的事件发布者的类型和属性.

    既然是key的value发生改变,那么一定是在key的setter方法的时候,发出通知.
    所以开始尝试自己模拟最简单的第一版KVO.

    核心思想是:当一个对象的某个属性发生改变时(也就是调用setter方法的时候),通知事件订阅者执行某些操作.

    //事件发布者的代码声明
    #import <Foundation/Foundation.h>
    
    @class ObjObserver;//事件订阅者
    
    @interface EventSender : NSObject
    
    @property (nonatomic,copy) NSString *name;
    
    - (void)myAddObserver:(ObjObserver*)observer forKeyPath:(NSString *)path;
    
    @end
    
    //事件发布者的代码实现
    #import "EventSender.h"
    #import "ObjObserver.h"
    
    @interface EventSender ()
    
    @property (nonatomic,strong) ObjObserver *observer;
    
    @end
    
    @implementation EventSender
    
    - (void)myAddObserver:(ObjObserver *)observer forKeyPath:(NSString *)path
    {
        //绑定事件响应者
        if(observer == nil) return;
        self.observer = observer;
    }
    
    - (void)setName:(NSString *)name
    {
        _name = name;
        //在name属性发生改变时执行事件响应者的相关函数
        if (self.observer != nil) {
            [self.observer methodForKvo:name];
        }
    }
    
    @end
    

    事件响应者的相关代码

    #import "ObjObserver.h"
    
    @implementation ObjObserver
    
    - (void)methodForKvo:(NSString *)value
    {
        NSLog(@"模拟KVO变化的第一版成功!");
        NSLog(@"变化的属性值是:%@",value);
        
    }
    
    @end
    
    

    main.m文件

    
    #import <Foundation/Foundation.h>
    #import "EventSender.h"
    #import "ObjObserver.h"
    
    int main(int argc, const char * argv[]) {
        //KVO - key/value/observering
        //当某个对象的某个属性值发生变化时,会通知观察者执行某些特定的操作.
        
        //注册事件发布者
        EventSender *es = [[EventSender alloc] init];
        
        //注册KVO观察者
        ObjObserver *ob = [[ObjObserver alloc] init];
        
        //添加观察者
        [es myAddObserver:ob forKeyPath:@"name"];
        
        es.name = @"事件发布者对象者调用setter方法";
        
        return 0;
    }
    
    

    最后执行结果截图:

    尝试实现KVO第一版V1.0

    最后粗浅的结论:
    KVO本质上,就是两个对象.
    一个事件发布者,在自己的某些属性的值发生改变时,通知事件响应者执行某些方法.
    一个是事件响应者,被事件发布者绑定到自己的某些属性的改变行为上.当属性发生改变时
    被动的被事件发布者执行相关的函数.

    画一张自己理解的图:

    KVO简单理解

    相关文章

      网友评论

        本文标题:iOS学习心得之:KVO

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