iOS底层原理探究之----KVC

2024-02-08 13:18
文章标签 原理 底层 ios 探究 kvc

本文主要是介绍iOS底层原理探究之----KVC,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

不管是平常开发还是找工作面试中,KVC、KVO的原理都是面试官比较喜欢问的问题。最近抽时间研究了一下KVC和KVO的实现原理,本想着一篇文章就可以说完,等研究完才发现不看不知道,一看吓一跳。KVC和KVO都有很多内容可以研究,所以分为两篇分享,第一篇分享KVC的底层原理。
本次分享准备从这几个方面入手:
1、概念定义
2、原理介绍
3、自己实现
4、使用场景

一、概念定义

KVC:Key-value coding (键-值编码)
苹果开发者文档中有这么一句话:
苹果文档
大意就是要想理解KVO必须首先理解KVC!足可见KVC的重要性。
概念:允许开发者通过key直接访问对象的属性方法或者成员变量,而不需要调用明确的存取方法。
实际上,KVC是对NSObject的扩展:NSKeyValueCoding,当然其中对NSArray、NSDictionary、NSMutableDictionary、NSOrderedSet、NSSet也添加了扩展,更方便使用。
其中主要提供了以下四个方法,当然还有很多其他方法,可以在苹果文档中查看:

- (nullable id)valueForKey:(NSString *)key;
- (void)setValue:(nullable id)value forKey:(NSString *)key;
- (nullable id)valueForKeyPath:(NSString *)keyPath;
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;

这些也是我们平常使用KVC使用最多的方法。

二、原理介绍

不知道大家在平常使用KVC的时候有没有思考这些问题:
Q1:不管是set还是get,只需要传入一个key字符串就可以存取,为什么?
Q2:如果类中没有相应的属性是否一定不能存取?
带着这样的问题我们研究一下KVC的实现原理。通过查阅苹果的官方文档和介绍,我们就可以了解到,在我们看似简单的API调用下,苹果其实是有一套完整的搜索规则,我们分set和get分别说明如下:

setValue:(id)value forKey:(NSString *)key
  • set的搜索规则如下

1.查找set<Key>:或_set<Key>命名的setter,按照这个顺序,如果找到的话,调用这个方法并将值传进去(根据需要进行对象转换)。
2.如果没有发现一个简单的setter,但是accessInstanceVariablesDirectly类属性返回YES,则查找一个命名规则为_<key>、_is<Key>、<key>、is<Key>的实例变量。根据这个顺序,如果发现则将value赋值给实例变量。
3.如果没有发现setter或实例变量,则调用setValue:forUndefinedKey:方法,并默认提出一个异常,但是一个NSObject的子类可以提出合适的行为。

上面提到了一个类属性accessInstanceVariablesDirectly

 + (BOOL)accessInstanceVariablesDirectly

它表示是否允许读取实例变量的值,如果为YES则在KVC查找的过程中,从内存中读取属性、实例变量的值。如果不允许外界通过KVC对我们的私有属性和成员变量进行操作,则可以设置此值为NO。
set的规则相对比较简单,相信大家都能看懂。我们也可以按照这个搜索顺序自己验证是否符合。(实现两个setter方法以及添加四种成员变量,然后依次注释掉后检查是不是按照上面的顺序进行赋值操作。)

  • get的搜索规则
    get的搜索规则相对于set就有点复杂了

1.通过getter方法搜索实例,例如get<Key>, <key>, is<Key>, _<key>的拼接方案。按照这个顺序,如果发现符合的方法,就调用对应的方法并拿着结果跳转到第五步。否则,就继续到下一步。
2.如果没有找到简单的getter方法,则搜索其匹配模式的方法countOf<Ke

这篇关于iOS底层原理探究之----KVC的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/691150

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

java程序远程debug原理与配置全过程

《java程序远程debug原理与配置全过程》文章介绍了Java远程调试的JPDA体系,包含JVMTI监控JVM、JDWP传输调试命令、JDI提供调试接口,通过-Xdebug、-Xrunjdwp参数配... 目录背景组成模块间联系IBM对三个模块的详细介绍编程使用总结背景日常工作中,每个程序员都会遇到bu

Python中isinstance()函数原理解释及详细用法示例

《Python中isinstance()函数原理解释及详细用法示例》isinstance()是Python内置的一个非常有用的函数,用于检查一个对象是否属于指定的类型或类型元组中的某一个类型,它是Py... 目录python中isinstance()函数原理解释及详细用法指南一、isinstance()函数

java 恺撒加密/解密实现原理(附带源码)

《java恺撒加密/解密实现原理(附带源码)》本文介绍Java实现恺撒加密与解密,通过固定位移量对字母进行循环替换,保留大小写及非字母字符,由于其实现简单、易于理解,恺撒加密常被用作学习加密算法的入... 目录Java 恺撒加密/解密实现1. 项目背景与介绍2. 相关知识2.1 恺撒加密算法原理2.2 Ja