什么是KVO?

KVO(Key-Value Observing)键值观察,是一种通过对对象的某一个属性添加观察者,一旦这个属性值发生变化,就会通知当前观察者的一种机制。

该如何使用?

1.注册,指定被观察者的属性

 [object addObserver:self forKeyPath:key options:NSKeyValueObservingOptionNew context:nil];

参数说明:

object:被观察的对象

observer:观察者对象

keyPath:被观察对象的属性名称

NSKeyValueObservingOptions:有4个值

NSKeyValueObservingOptionNew 监听它的新值

NSKeyValueObservingOptionOld  监听它的旧值

NSKeyValueObservingOptionInitial 监听初始化

NSKeyValueObservingOptionPrior 分2次调用。监听旧值和新值

context: 可以带入一些参数,任何类型都可以,强制转就可以。

2.实现回调函数

-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"keyPath---->%@ change--->%@",keyPath,change);
}

参数说明:

keyPath:被观察对象的属性名称

object:被观察的对象

change:新值或者旧值

context:对应的context

3. 移除观察

 [object removeObserver:self forKeyPath:@"name"];

参数说明:

object:被观察的对象

observer:观察者对象

keyPath:被观察对象的属性名称

写个测试程序测试一下:

Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject
{
@private
NSString *address; } @end

Person.m

#import "Person.h"
#import "Car.h" @interface Person () @property (nonatomic ,strong) NSString *name; @property (nonatomic,strong)Car *car; @end @implementation Person -(id)init
{
self=[super init];
if(self){
self =[super init];
self.car=[[Car alloc]init];
}
return self;
} @end

Car.h

#import <Foundation/Foundation.h>

@interface Car : NSObject

@end

Car.m

#import "Car.h"

@interface Car()

@property (nonatomic ,strong) NSString *brand;

@end

@implementation Car

@end

测试代码:

//添加KVO观察者
-(void)addObserver
{
[self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld context:@"haha"]; [self.person addObserver:self forKeyPath:@"address" options:NSKeyValueObservingOptionNew context:nil]; [self.person addObserver:self forKeyPath:@"car.brand" options:NSKeyValueObservingOptionNew context:nil];
} -(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"keyPath---->%@ change--->%@",keyPath,change);
} //移除KVO观察者
-(void)removeObserver
{
[self.person removeObserver:self forKeyPath:@"name"];
[self.person removeObserver:self forKeyPath:@"address"];
[self.person removeObserver:self forKeyPath:@"car.brand"];
}

随机推荐

  1. android PreferenceFragment

    初始化: public SettingPreferenceFragment() { } public void setArguments(Bundle bundle){ String targetId ...

  2. css变形 transform【转】

    transition:过度属性 transition-property 规定设置过度效果的css属性的名称,默认可以写all transition-duration 规定完成过度效果需要多少秒或毫秒 ...

  3. ::after::before清除浮动原理

    先来看一段代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  4. mac 下面wireshark 找不到网卡

    终端上面,执行如下命令:   sudo chgrp admin /dev/bpf*   sudo chmod g+rw /dev/bpf* http://www.9upk.com/article/25 ...

  5. 阻止check事件冒泡

    在Datagrid中添加了checkbox,想实现的效果是: 1.点击行中任意位置,该行的复选框变为选中状态,同时该行也获得焦点: 2.点击复选框,复选框打勾,同时该行获取焦点. 要实现功能1,用到d ...

  6. PHP以星号隐藏用户名手机和邮箱

    <?php class Hidesatr{ function hide_star_do($str) { //用户名.邮箱.手机账号中间字符串以*隐藏 if (strpos($str, '@')) ...

  7. Ubuntu下OpenCV不能被某个python版本识别

    Ubuntu下OpenCV不能被某个python版本识别 Solution: 可以进入相应版本的python,查看该python的path: python import sys print(sys.p ...

  8. 在 CentOS 7 中安装 MySQL 8

    准备 本文环境信息: 软件 版本 CentOS CentOS 7.4 MySQL 8.0.x 安装前先更新系统所有包 sudo yum update 安装 1. 添加 Yum 包 wget https ...

  9. JS存储cookie读取cookie删除cookie详细用法

    假设有这样一种情况,在某个用例流程中,由A页面跳至B页面,若在A页面中采用JS用变量temp保存了某一变量的值,在B页面的时候,同样需要使用JS来引用temp的变量值,对于JS中的全局变量或者静态变量 ...

  10. iOS 线程之GCD的高级使用方法

    之前的一篇关于线程的blog已经为大家介绍了GCD的简单使用方式及样例说明,今天因为项目中有特殊的应用GCD的实例,为大家介绍两种特殊需求的使用GCD的方法. 目的:实现一件事情做完,再做下一件事情. ...