iOS 再谈KVC、 KVO
故事背景:大厂面试,又问道了基本的kvc kvo的原理和使用,由于转了前端,除了个setter和getter,我全忘记了,其实还是没有理解记忆,下面再看一下kvc 和kvo ,总结一个让人通过理解而无法忘记的方法:
---------------------------KVC---------------------------------
(注意:所谓聊一下:kvc 的机制,就是kvc的定义+使用方法,及该方法的原理)
KVC定义:(Key-value coding) 从名字就能看出,kvc的意思就是:键-值 编码,是一种访问某个对象属性的方法 或者叫一种模式;
1. 使用详解:通常情况下我们会应用点语法(xxx.name)来访问一个对象中的属性。通过KVC,我们可以只使用属性名字的字符串,(可以是你自己定义的名字,也就是键)来间接访问和操作对象的属性,就是所谓的各种 :setValue:(你想操作的值) forKey:(你定义的名字-键) 方法,但其实在KVC的底层实现中,还是会调用相应属性的存取方法,如果对应的存取方法存在的话。同时,利用KVC可以访问对象中的私有变量,而不仅仅是公开的属性。在NSKeyValueCoding.h的头文件中可以看到相应的方法声明。
2.KVC的设置变量值的搜索模式:(使用原理)
(1)首先会搜索对应属性名称的存取方法,也就是setter以及getter方法,如果有就直接调用存取方法。
(2)如果要访问的变量没有存取方法,也就是setter以及getter方法,(例如私有的实例变量或者没有自动生成存取方法的属性值),那么会首先检查类方法检查类方法:+ (BOOL)accessInstanceVariablesDirectly,如果该类方法返回Yes,就会按照名称顺序:_key、_isKey、key、isKey来搜索实例变量;如果该类方法返回NO,就会调用setValue:forUndefinedKey: 或者 valueForUndefinedKey:的方法。
3.KVC 与点语法比较:
用点语法编译器会做预编译检查,访问不存在的属性编译器会报错,但是用 KVC 方式编译器无法做检查, 如果有错误只能运行的时候才能发现。相比点语法用 KVC 方式 KVC 的效率会稍低一点,但是较为灵活,可以在程序运行时决定访问哪些属性,并且用 KVC 可以访问对象的私有成员变量,访问速度方面,通过点语法访问变量比使用KVC访问变量要快,因为点语法是直接访问存取方法,没有响应复杂的搜索机制。
---------------------------KVO---------------------------------
(注意:所谓kvo 的机制,也同样就是kvo是什么 ,它的使用方法 addObserve:self forkeypath:"你定义的键名称",及该方法的原理)
什么是KVO?
KVO( Key-Value Observing),也就是键值观察:键值观察是一种通知机制,或者叫通知方法;能够使得被观察对象的属性在发生变化的时候通知观察者,类似于一种target-action的机制,是Cocoa中观察者模式的一种实现。通常键值观察会协同键值编码KVC来一起使用。在NSKeyValueObserving.h头文件中可以看到跟KVO相关的方法。
KVO的实现原理:
KVO的实现原理,其实就是运行时使用了指针替换或者叫混淆,也就是所谓的 isa-swizzling 方法(这个英语不用记),本质是一种制造 “指向替换 ”的方法。每一个实例和类都有一个isa指针,当然无法直接访问(可间接访问)。实例变量的isa指针指向对应的类,而类的isa指针指向其元类(啥是元类看下面),在方法调用的运行时阶段实现,其实就是根据isa指针找到所在的类或者元类,接着在类或者元类的方法列表中寻找。
具体的指针替换机制就是:当某个实例(例如Person类的实例per,继承自NSObject)作为被观察者,调用KVO的 addObserver方法时,在运行时会动态生成Person的一个特殊的子类,之所以说它特殊,是因为这个子类的名称是按照规则命名的,对于Person类,就会创建一个名为NSKVONotifying_Person的子类(类名前缀就是规定的NSKVONotifying_),在这个子类中,运行时会重写要监听属性的setter方法(注意对于没有监听的属性,是不会重写setter方法的),class方法,dealloc方法,还有一个名为_isKVOA的方法。。。然后重点来了,运行时会把实例Person类的 isa 指针指向修改的类:原本是指向Person类,修改为指向NSKVONotifying_Person类,也就是新创建的 “特殊” 子类,利用KVO调用的:被监听属性的存取方法,就是这个子类重写的存取方法。
*******元类******
1.什么是元类
对象的isa指针指向类,类也是一种对象被称为类对象,其isa的指向是元类。
元类是系统给的,定义和编译是由编译器完成的。
每个类都有独一无二的元类,用来存储类方法。
可以通过下面的图来解释:
对象 --> 类 --> 元类 --> NSobject,NSObject指向自身。
参考链接:【iOS】—— 继承者链_ios 元类-CSDN博客
参考链接:
KVO原理分析 - 简书
iOS基础黑科技:KVO(键值观察)以及KVC(键值编码) - 简书
iOS KVC和KVO详解 - 简书
iOS KVC和KVO详解 - 简书
相关文章:
iOS 再谈KVC、 KVO
故事背景:大厂面试,又问道了基本的kvc kvo的原理和使用,由于转了前端,除了个setter和getter,我全忘记了,其实还是没有理解记忆,下面再看一下kvc 和kvo ,总结一个让人通过理解而无法忘记的方法&a…...
java、excel表格合并、指定单元格查找、合并文件夹
#创作灵感# 公司需求 记录工作内容 后端:JAVA、Solon、easyExcel、FastJson2 前端:vue2.js、js、HTML 模式1:合并文件夹 * 现有很多文件夹 想合并全部全部的文件夹的文件到一个文件夹内 * 每个部门发布的表格 合并全部的表格为方便操作 模…...
最基础版编译运行Java(纯小白)
流程图: ⚠ 需要先安装JDK (Java Development Kit) 1. 写文件 首先写好自己的“文件”,可以用Sublime Text等文本编辑器写,还可以直接新建文本文档写一个.txt文件。 以编写一个HelloWorld程序为例: public class HelloWorld{p…...
六西格玛项目助力,手术机器人零部件国产化稳中求胜——张驰咨询
项目背景 XR-1000型腔镜手术机器人是某头部手术机器人企业推出的高端手术设备,专注于微创手术领域,具有高度的精确性和稳定性。而XR-1000型机器人使用的部分核心零部件长期依赖进口,特别是高精度电机、关节执行机构和视觉系统等,…...
Python爬虫系列(一)
目录 一、urllib 1.1 初体验 1.2 使用urllib下载网页、图片、视频等 1.3 反爬介绍 1.4 请求对象定制 1.5 get请求的quote方法 1.6 多个参数转成ascii编码 1.7 post请求 1.8 综合案例演示 一、urllib 1.1 初体验 # urllib是python默认带的,无需额外下载 i…...
# vim那些事...... vim删除文件全部内容
vim那些事… vim删除文件全部内容 1、在 Vim 中删除整个文件的内容,可以使用以下命令: 1)打开 Vim,并编辑你想要清空的文件。 2)按 Esc 确保你不在插入模式,而在命令模式。 3)输入 gg 跳转到…...
Selinux及防火墙
一,selinux简介: SELinux(Security-Enhanced Linux)是一个Linux内核安全模块,旨在提供强制访问控制(MAC)机制,以增强系统的安全性。由美国国家安全局(NSA)开…...
业绩代码查询实战——php
一、一级代码显示职员 foreach($data_职员信息 as $key > $value){//$where_查询分类$where_查询通用;//$dat分类one $业绩提成->where($where_查询分类)->order("CreateDate desc")->select();if($value[haschildname]0 && $value[key] !"…...
内网穿透技术选型PPTP(点对点隧道协议)和 FRP(Fast Reverse Proxy)
PPTP(点对点隧道协议)和 FRP(Fast Reverse Proxy)是两种实现内网穿透的技术,但它们的工作原理、使用场景和特点有很大区别。以下是它们的详细比较: PPTP(Point-to-Point Tunneling Protocol&am…...
信号与噪声分析——第三节:随机过程的统计特征
随机过程的定义: 随机过程是一种数学模型,用来描述系统或现象在时间或者空间上随之变化的不确定性。 一个随机过程的数字特征 1.数学期望(统计平均值): 表示为 数学期望是随机过程在时间 t 上的平均值,通常…...
nginx(四):如何在 Nginx 中配置以保留真实 IP 地址
如何在 Nginx 中配置以保留真实 IP 地址 1、概述2、nginx配置示例2.1、配置说明2.2、客户端获取真实IP2.2.1、代码说明 3、插曲4、总结 大家好,我是欧阳方超,可以我的公众号“欧阳方超”,后续内容将在公众号首发。 1、概述 当使用nginx作为…...
docker对nginx.conf进行修改后页面无变化或页面报错
可能是因为没有重启nginx容器 可以执行 docker restart nginx 重启nginx试试 引入了其他的配置文件 本人安装的是docker默认的nginx,自带了一个default.conf的配置文件,并且在nginx.conf中还引入了这个文件,后面我还对nginx.conf添加了一个…...
SpringCloudGateway — 网关路由
Spring Cloud Gateway 是 Spring 提供的一个高效、灵活的 API 网关解决方案,基于 Spring 5、Spring Boot 2 和 Project Reactor,具有高并发和低延迟的特点。它用于在微服务架构中对外提供统一的入口,处理请求的路由、过滤、负载均衡等功能。 …...
docker pull 拉取镜像失败,使用Docker离线包
1、登录并注册Github,然后在Github中搜索并打开“wukongdaily/DockerTarBuilder” 项目,在该项目主页点击“Fork”。 然后点 “Create Fork”,将项目创建到自己的Github主页。 2、接着在自己创建过来的这个项目中点击“Actions” 3、然后…...
轻松理解操作系统 - 轻松了解 inode 是如何管理文件的
Linux 由于其开源、比较稳定等特点统治了服务端领域。也因此,学习Linux 系统相关知识在后端开发等岗位中变得越来越重要,甚至可以说是必不可少的。 因为它的广泛应用,所以在程序员的日常工作和面试中,它都是经常出现的。它的开源特…...
go中Println和Printf的区别
Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 go中Println和Printf的区别 package mainimport ( "fmt" )//TIP To run your code, right-click the c…...
C++现代教程七之模块
优点 编译时间减少:模块消除了重复解析和编译头文件的需要,从而显著减少了编译时间。特别是在大型项目中,这一点尤为重要。更好的封装性:模块允许更严格的封装,可以明确地控制哪些符号对外可见。这有助于减少命名冲突和…...
AVLTree
1.AVL树的概念 二叉搜索树虽然可以提高查找的效率,但是如果数据有序或者接近有序,二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。为了解决该问题,于是就有了AVLTree。即当向二叉搜索树中插入…...
Java面向对象 C语言字符串常量
1. (1). package liujiawei;public class Phone {String brand;double price;public void call(){System.out.println("手机打电话");}public void play(){System.out.println("手机打游戏");} } public class phonetest {public…...
SpringBoot+Thymeleaf电商系统
> 这是一个基于SpringBootThymeleafBootstrap实现的简单电商系统。 > 实现了用户浏览、添加购物车、商品管理等功能,并支持响应式布局。 > 本项目适合JAVA初学者作为入门学习项目 一、部分界面演示 二、技术栈 技术栈中文描述Spring Boot快速开发框架…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...
TCP/IP 网络编程 | 服务端 客户端的封装
设计模式 文章目录 设计模式一、socket.h 接口(interface)二、socket.cpp 实现(implementation)三、server.cpp 使用封装(main 函数)四、client.cpp 使用封装(main 函数)五、退出方法…...
spring boot使用HttpServletResponse实现sse后端流式输出消息
1.以前只是看过SSE的相关文章,没有具体实践,这次接入AI大模型使用到了流式输出,涉及到给前端流式返回,所以记录一下。 2.resp要设置为text/event-stream resp.setContentType("text/event-stream"); resp.setCharacter…...
Java设计模式:责任链模式
一、什么是责任链模式? 责任链模式(Chain of Responsibility Pattern) 是一种 行为型设计模式,它通过将请求沿着一条处理链传递,直到某个对象处理它为止。这种模式的核心思想是 解耦请求的发送者和接收者,…...
