iOS开发————通信方式之KVO

KVO即键值观察者,它提供了一个观察者模式,用于监听某个对象属性值的变化,可以实现一个观察者,一个被观察者,多个接收者之间的通信关系。


 KVO的工作流程:

 1.被观察者属性发生变化(child对象的cleanValue发生变化)

 2.观察者监听到属性的变化(KVO帮我们实现了观察者的业务逻辑)

 3.观察者会调用观察者方法通知到事件的接收者(观察者通知到保姆)

 4.事件接收者响应这个事件。


在接收者类中添加小孩的观察者,对象写self,下面实现观察者方法,其中改变小孩的相关属性值,最后手动移除观察者


相关方法:

1、添加观察者的方法:

_child:被观察者

         addObserver:事件的接收者

         options:表示在观察者方法的change参数中能够获取的值。

         context:传递的参数

        [_childaddObserver:selfforKeyPath:@"cleanValue"options:NSKeyValueObservingOptionNewcontext:NULL];

2、观察者响应事件的方法:

     //keyPath:被观察者监听的属性名

//object:被观察者

//change:是一个字典,提供了关于KVO的有效信息,比如key:new时表示的是属性变化后的新值,key:old表示的是属性变化前的旧值

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {}


举例:小孩脏了,需要保姆来打理

给小孩添加一个观察者,事件的接收者是保姆,观察者把小孩洁净度这个属性值传递到保姆,保姆去响应打理小孩的方法。

#import "Child.h"

@implementation Child

- (instancetype)init {
    
    if (self = [super init]) {
        
        _cleanValue = 100;
        _happyValue = 100;
    }
    
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
    
    return self;
}

- (void)timerAction:(NSTimer *)timer {
    
    //1.只有通过两种方式进行属性值的设置才能被KVO所监听到
//    (1)用setter方法
//    (2)KVC
    
    //这种方法不能被KVO监听到
//    _cleanValue--;
//    _happyValue--;
    
    self.cleanValue = _cleanValue - 1;
    
    self.happyValue = _happyValue - 1;

    NSLog(@"cleanValue:%li,happyValue:%li", _cleanValue, _happyValue);
    
    
}

@end



#import "Nanny.h"
#import "Child.h"

@implementation Nanny

- (instancetype)initWithChild:(Child *)child {
    
    if (self = [super init]) {
        
        _child = child;
        
        //使用KVO来监听小孩属性值的变化,需要给小孩添加一个观察者,必须在注册观察者以后才能够监听到小孩属性值的变化。
        /*
         给被观察者注册一个观察者,来监听被观察者属性的变化。
         _child:被观察者
         addObserver:事件的接收者
         options:表示在观察者方法的change参数中能够获取的值。
         context:传递的参数
         */
        
        [_child addObserver:self forKeyPath:@"cleanValue" options:NSKeyValueObservingOptionNew context:NULL];
        [_child addObserver:self forKeyPath:@"happyValue" options:NSKeyValueObservingOptionNew context:NULL];
        

    }
    
    return self;
    
}


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    
//keyPath:被观察者监听的属性名
//object:被观察者
//change:是一个字典,提供了关于KVO的有效信息,比如key:new时表示的是属性变化后的新值,key:old表示的是属性变化前的旧值
    NSLog(@"%@", change);
    
    if ([keyPath isEqualToString:@"cleanValue"]) {
        NSNumber *newValue = change[@"new"];
        if ([newValue integerValue] < 95) {
            //保姆针对小孩脏了事件的处理代码
            NSLog(@"保姆给小孩洗白白");
            _child.cleanValue = 100;
            
            
        }

    }
    else if ([keyPath isEqualToString:@"happyValue"]) {
        
        NSNumber *newValue = change[@"new"];
        if ([newValue integerValue] < 90) {
            //保姆针对小孩脏了事件的处理代码
            NSLog(@"保姆逗小孩开心");
            _child.happyValue = 100;
            
            
        }
        
    }
    
    
    //用KVO也实现了小孩和保姆之间的通信,小孩可以脱离保姆而存在,进行解耦合,如果想换一个照顾小孩的类,只要在类中添加观察者,并且实现观察者方法就可以。
    
}

- (void)dealloc {
    
    //在保姆对象被释放之前,要移除观察者。ARC无法帮我们完成。
    [_child removeObserver:self forKeyPath:@"cleanValue"];
    [_child removeObserver:self forKeyPath:@"happtValue"];
    
}

@end



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值