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

来源:互联网 发布:双程网络剧 土豆 编辑:程序博客网 时间:2024/06/06 14:11

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



1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孩子断奶一直哭怎么办 突然喜欢咬指甲怎么办 孩子喜欢咬指甲怎么办 小孩喜欢咬指甲怎么办 宝宝喜欢咬指甲怎么办 婴儿含奶睡觉怎么办 宝宝2岁还吃母乳怎么办 宝宝总抠屁眼怎么办 一年级的孩子厌学怎么办 孩子就是不说话怎么办 感觉自己反应慢怎么办 小学生数学基础不好怎么办 数学考差了怎么办 孩子考试成绩差该怎么办 大学高数听不懂怎么办 遇上自私的父母怎么办 小孩一年级数学不好怎么办 数学考试考不好怎么办 孩子奥数学不好怎么办 孩子下笔太重怎么办 小孩子写字太重怎么办 经常对小孩发火怎么办 对小孩发火后悔怎么办 小孩子不喜欢学数学怎么办? 孩子心里素质差怎么办 三年级语文太差怎么办 宝宝一年级很笨怎么办 一年级孩子太笨怎么办 孩子学习脑子笨怎么办 四年级孩子数学差怎么办 中考考不好了怎么办 初中没学高中怎么办 数学基础差该怎么办 三年级数学成绩差怎么办 夫妻差6岁怎么办 初一数学很差劲怎么办 三年级孩子成绩差怎么办 初中数学成绩不好怎么办 大人不会算数学怎么办 小学初数学不好怎么办 初中生数学计算能力差怎么办