当前位置: 首页 > news >正文

【iOS】KVC

MVC

  • 简介
  • KVC常见的用法
    • 常见的API
    • Key与KeyPath
  • KVC的强大功能
    • 批量存取值功能
  • 字典转化模型
  • KVC的底层原理
    • 赋值原理
    • 取值原理

简介

KVC全称Key-Value-Coding,中文名称为键码编值,可以通过一个key来访问某一个属性。

KVC提供了一种间接访问其属性方法或者成员变量的机制,可以通过字符串来访问对应的属性方法或成员变量。

他是一个非正式的Protrocol,提供一种机制来间接访问对象的属性,而不是通过调用Setter、Getter方法访问。KVO就是基于KVC实现的关键技术之一

KVC常见的用法

常见的API

//通过KeyPath(路径)来设值
- (void)setValue:(id)Value forKeyPath:(NSString *)keyPath;
//通过Key来设值
- (void)setValue:(id)Value forKey:(NSString *)key;
//通过keyPath来取值
- (id)valueForkeyPath:(NSString *)keyPath;
//通过Key来取值
- (id)valueForkey:(NSString *)key;

Key与KeyPath

Key:只能接受当前类所具有的属性,不管是自己的,还是从父类继承过来的。

KeyPath:除了能接受当前类的属性,还可以接受当前类属性的属性,即可以接受一个关系链。

下面举两个例子来说明:

在这里插入图片描述

在上面图片中,我们可以看到常见API的使用方法。

KVC的强大功能

批量存取值功能

批量存值操作

KVC中,可以根据一组给定的key来获取到一组Value,并且以字典的形式返回。

- (NSDictionary<NSString *, id> *)dictionaryWithValuesForKeys:(NSArray<NSString *> *)keys;

批量赋值操作

//通过该方法允许通过一个字典一次性设置多个属性的值,不需要逐个去使用- (void)setValue:(id)Value forKey:(NSString *)key;

- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues;

举例说明

#import <Foundation/Foundation.h>
#import "Person.h"int main(int argc, const char * argv[]) {@autoreleasepool {Person* p1 = [[Person alloc] init];[p1 setValue:@"eric" forKey:@"name"];[p1 setValue:@"19" forKey:@"age"];[p1 setValue:@"man" forKey:@"sex"];NSDictionary* dic = [p1 dictionaryWithValuesForKeys:@[@"name", @"age", @"sex"]];NSLog(@"%@", dic);NSDictionary* dic1 = @{@"name":@"jack", @"age":@30, @"sex":@"women"};Person* p2 = [[Person alloc] init];[p2 setValuesForKeysWithDictionary:dic1];NSLog(@"name = %@, age = %@, sex = %@", p2.name, p2.age, p2.sex);}return 0;
}

打印结果

在这里插入图片描述

字典转化模型

如果modeldic不匹配,可以重写方法-(void)setValue:(id)value forUndefinedKey:(NSString *)key.

#import "Person.h"@implementation Person- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{if([key isEqualToString:@"sex"]) {self.sex = (NSString*) value;}
}@end

KVC的底层原理

赋值原理

在这里插入图片描述

结合上图,来看看KVC赋值的原理:

  • 首先会查找setKey_setKey方法,如果找到,那么直接调用方法赋值。
  • 如果没有找到方法,则会查看+ (BOOL)accessInstanceVariablesDirectly(控制是否可以直接访问实例变量)是否为YES(默认为YES)。
  • 若为YES,则会按照_key,_isKey,key,isKey的顺序查找成员变量,如果找到则会直接给成员变量赋值,找不到就抛出NSUnknownException异常。
  • 若为NO,则会调用setValue:ForUndefinedKey:并且抛出NSUnknownException异常。

取值原理

在这里插入图片描述

结合上图,来看看KVC取值的原理:

  • 首先会按照getKey,key,isKey,_key的混序查找方法,如果找到方法,直接调用方法。
  • 若未找到方法,则查看+ (BOOL)accessInstanceVariablesDirectly(控制是否可以直接访问实例变量)是否为YES(默认为YES)。
  • 若返回为YES,则按照_key,_isKey,key,isKey的顺序去查找成员变量,如果找到成员变量,则直接取值,未找到则抛出NSUnknownException异常。
  • 若为NO,则会调用valueForundefinedKey:并且抛出NSUnknownException异常。

http://www.mrgr.cn/news/30411.html

相关文章:

  • ubuntu18.04上存储空间分析
  • 解决C盘空间不足的三种方案
  • 第七部分:2. STM32之ADC实验--AD多通道(AD采集三路传感器模块实验:光敏传感器、热敏传感器、反射式传感器附赠温湿度传感器教程)
  • 在Linux上部署(MySQL Redis Elasticsearch等)各类软件
  • VSCode中python插件安装后无法调试
  • 《深入浅出Apache Spark》系列③:Spark SQL解析层优化策略与案例解析
  • 95分App引领年轻人省钱赚钱新风尚,闲置也能变宝藏
  • 内存管理篇-27寄存器映射:ioremap
  • 打工人、设计师必备的AI抠图工具
  • 索引的介绍
  • 音视频入门基础:AAC专题(10)——FFmpeg源码中计算AAC裸流每个packet的pts、dts、pts_time、dts_time的实现
  • chapter15-泛型——(自定义泛型)——day20
  • 力扣232:用栈实现队列
  • 【python】多线程
  • Java 之网络编程小案例
  • 前端 Vue.js + 后端 Flask/Django 完美结合:教你打造高效全栈应用的秘诀!
  • OpenGL 原生库1 窗口
  • SDKMAN!关联已安装JDK
  • 3.数据类型
  • 【Webpack--011】配置开发和生产模式的webpack.config.js
  • Java数据结构 时间复杂度和空间复杂度
  • PMP 报考条件是有哪些?
  • Linux命令:对文本文件的内容进行排序的工具sort详解
  • 代码随想录算法训练营43期 | Day 21 —— 108.将有序数组转换为二叉搜索树、 538.把二叉搜索树转换为累加树
  • Vue2接入高德地图API实现搜索定位和点击获取经纬度及地址功能
  • 多路径文件批量下载工具V1.0.3-支持批量下载文件到单独文件夹的工具-供大家学习研究参考