iOS KVC与KVO简介

栏目: IOS · 发布时间: 6年前

内容简介:KVC是在iOS的开发中,可以通过也就是说我们可以在程序运行时动态地访问和修改对象的属性。

KVC是 Key Value Coding 的缩写,即 键值编码

在iOS的开发中,可以通过 key 名直接访问实例对象的属性,而不需要调用明确的存取方法。

也就是说我们可以在程序运行时动态地访问和修改对象的属性。

KVC的定义都是对 NSObject 的扩展来实现的 NSObject(NSKeyValueCoding) ,所以对于所有继承了 NSObject 的类型,都能使用 KVC 。(PS:一些纯 Swift 类和结构体是不支持 KVC 的,因为没有继承 NSObject )

1.2 KVC中的常用方法

在程序开发过程中,最常用的KVC方法有四个:

// 通过Key来获取对象属性的值
- (nullable id)valueForKey:(NSString *)key;

 // 通过Key来设置对象属性的值
- (void)setValue:(nullable id)value forKey:(NSString *)key;

// 通过复合路径KeyPath来获取对象属性的值
- (nullable id)valueForKeyPath:(NSString *)keyPath; 

// 通过复合路径KeyPath来设置对象属性的值
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;  
复制代码

1.3 KVC的使用

首先,我们定义两个简单的类,在代码中简单使用一下上面的方法:

  • 员工类QiStaff.h:
@interface QiStaff : NSObject

// 员工编号
@property (nonatomic, strong) NSString *staffId;
// 员工名字
@property (nonatomic, strong) NSString *staffName;

@end
复制代码
  • 公司类QiCompany.h
#import <Foundation/Foundation.h>
#import "QiStaff.h"

@interface QiCompany : NSObject

// 公司名字
@property (nonatomic, strong) NSString *name;
// 员工变量
@property (nonatomic, strong) QiStaff *staff;

@end
复制代码
  • 公司类QiCompany.m:
#import "QiCompany.h"

@interface QiCompany()

@property (nonatomic, strong) NSString *addr;

@end

@implementation QiCompany


@end
复制代码
  • KVC方法的具体使用过程:
- (void)aboutKVC {
    
    QiCompany *company=[[QiCompany alloc]init];
    [company setValue:@"QiShare" forKey:@"name"];
    [company setValue:@"北京市朝阳区酒仙桥路" forKey:@"addr"];
    NSLog(@"公司:%@  地址:%@", company.name, [company valueForKey:@"addr"]);
    
    QiStaff *staff = [[QiStaff alloc]init];
    company.staff = staff;
    [company setValue:@"1000119" forKeyPath:@"staff.staffId"];
    [company setValue:@"佩奇" forKeyPath:@"staff.staffName"];
    NSLog(@"员工id:%@  名字:%@", [company valueForKeyPath:@"staff.staffId"], [company valueForKeyPath:@"staff.staffName"]);
}
复制代码

日志输出:

2018-11-13 13:55:32.797847+0800 QiKVO&KVC[19722:585309] 公司:QiShare 地址:北京市朝阳区酒仙桥路

2018-11-13 13:55:32.798040+0800 QiKVO&KVC[19722:585309] 员工id:1000119 名字:佩奇

注:

1)方法中的 KeyPath 用于“复合路径”,例如 QiCompany 类中有一个 QiStaff 类型的属性,则 company.staff 就是一个“复合路径”;

2) KVC 可以操作对象的私有变量。

二、KVO

2.1 KVO介绍

KVO 是 Key Value Observing 的缩写,即 键值监听

键值监听是典型的基于观察者模式的应用。顾名思义,KVO可以通过监听 key ,来获得 value 的变化,用来在对象之间监听状态变化。

KVO的定义都是对 NSObject 的扩展来实现的 NSObject(NSKeyValueObserving) ,所以对于所有继承了 NSObject 的类型,都能使用 KVO

2.2 KVO中的常用方法

在开发过程中常用的KVO方法有两个,分别是添加观察者和移除观察者方法:

// 添加观察者
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

// 移除观察者
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

// 代理 监听值变的方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context;
复制代码
NSKeyValueObservingOptions 含义
NSKeyValueObservingOptionNew change字典中包括改变后的值。
NSKeyValueObservingOptionOld change字典中包括改变前的值。
NSKeyValueObservingOptionInitial 每次修改变量值时均触发KVO通知。(包括添加观察者之前的修改动作,而change字典中无相应的key-value)
NSKeyValueObservingOptionPrior 修改变量值之前和之后均立即触发KVO通知。(两次触发中,chang字典的内容不同,修改之前的通知change字典中有notificationIsPrior = 1键值对)

注:在我们日常开发中,我们一般取这个Options值为 NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld ,这时,当变量值被修改时,我们在change字典中既能得到新值,也能得到修改之前的值。

2.3 KVO的使用

我们在第一节所用的代码基础上进行修改,示例代码如下:

  • 员工类QiStaff.h:
#import <Foundation/Foundation.h>
#import "QiStaff.h"

@interface QiCompany : NSObject

// 公司名字
@property (nonatomic, strong) NSString *name;
// 员工变量
@property (nonatomic, strong) QiStaff *staff;

@end
复制代码
  • 公司类QiCompany.h:
#import <Foundation/Foundation.h>
#import "QiStaff.h"

@interface QiCompany : NSObject

// 公司名字
@property (nonatomic, strong) NSString *name;
// 员工变量
@property (nonatomic, strong) QiStaff *staff;

- (void)aboutKVO;

@end
复制代码
  • 公司类QiCompany.m:
#import "QiCompany.h"

@interface QiCompany()

@property (nonatomic, strong) NSString *addr;

@end

@implementation QiCompany

- (void)aboutKVO {

    self.staff = [[QiStaff alloc] init];
    self.staff.staffId = @"1000119";
    self.staff.staffName = @"佩奇";

    [self.staff addObserver:self forKeyPath:@"staffId" options:NSKeyValueObservingOptionNew context:nil];
    [self.staff addObserver:self forKeyPath:@"staffName" options:NSKeyValueObservingOptionNew context:nil];

    self.staff.staffId = @"1000120";
    self.staff.staffName = @"佩德罗";
}

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

    NSLog(@"keyPath = %@   object=%@   newValue=%@   context=%@", keyPath, object, [change objectForKey:@"new"], context);
}

- (void)dealloc {

    [self.staff removeObserver:self forKeyPath:@"staffId"];
    [self.staff removeObserver:self forKeyPath:@"staffName"];
}

@end
复制代码

日志输出:

2018-11-13 16:25:21.215872+0800 QiKVO&KVC[20986:895803] keyPath = staffId object=<QiStaff: 0x6000017286c0> newValue=1000120 context=(null)

2018-11-13 16:25:21.216040+0800 QiKVO&KVC[20986:895803] keyPath = staffName object=<QiStaff: 0x6000017286c0> newValue=佩德罗 context=(null)

PS:使用时, addObserverremoveObserver 需要成对出现,在销毁对象时移除监听。

工程源码: GitHub地址


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

High Performance Python

High Performance Python

Micha Gorelick、Ian Ozsvald / O'Reilly Media / 2014-9-10 / USD 39.99

If you're an experienced Python programmer, High Performance Python will guide you through the various routes of code optimization. You'll learn how to use smarter algorithms and leverage peripheral t......一起来看看 《High Performance Python》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具