OC对象 - KVO

Multisim14.0仿真(五十九)基于74LS161的24进制计数器应用设计 它具有同步预置、异步清零功能,支持并行数据加载,并可在计数使能控制下进行二进制计数。:低电平时,在下一个时钟上升沿加载输入数据(A, B, C, D)。(多个 74LS161D 串联构成 8 位、12 位等更长计数器)。低电平时,下一个时钟上升沿加载输入数据(A, B, C, D)。:低电平有效,立即清零计数器(不受时钟控制)。均为高电平时,每个时钟上升沿计数。:两者均为高电平时,计数器才能递增。:立即清零计数器(不受时钟控制)。(通过预置初始值控制计数范围)。(计数范围:0 ~ 15,即。 阅读详情

OC对象 - KVO

俗称“键值监听” ,用来监听某个属性值的改变

1. KVO基本使用

1.1 简单的KVO

  • 首先我们新建一个iOS的App项目
  • 新建ZSXPerson类
@interface ZSXPerson : NSObject

@property (nonatomic, assign) int age;

@end
@implementation ZSXPerson

@end
  • viewController 中创建ZSXPerson属性并初始化,然后添加KVO监听实例对象的age变化,接着通过 touchesBegan 点击屏幕的时候修改age值,来触发 KVO
#import "ViewController.h"
#import "ZSXPerson.h"

@interface ViewController ()

@property (nonatomic, strong) ZSXPerson *person1;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _person1 = [[ZSXPerson alloc] init];
    [_person1 addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"点击了屏幕");
    _person1.age = 20;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    NSLog(@"监听到 %@的%@的值发生变化:%@", object, keyPath, change);
}

- (void)dealloc {
    [_person1 removeObserver:self forKeyPath:@"age"];
}

@end
  • 运行项目,点击屏幕,查看控制台输出

  • 现在我们已经使用 KVO 正常监听 person 的 age 值变化

2. 观察给对象添加kvo监听和没有添加kvo监听的区别

2.1 增加person2对象

我们再增加一个person2属性并初始化,同样在点击屏幕的时候,给person2.age也赋值

此时点击屏幕,控制台确实只输出 person1 对象的监听变化

2.2 思考

  • 我们对person1和person2仅仅做了同样了age赋值操作,kvo是怎么做到添加了监听的对象才触发observeValue呢?

3. KVO底层实现探究

3.1 添加KVO前后,setAge方法发生了什么变化?

在添加KVO前后,分别打印一下方法实现的地址

发现person1 的 setAge 方法在添加完 KVO 监听后变化了,person2 是没有变化的

3.2 添加KVO前后,setAge到底走了什么方法

我们打印一下方法

  • 直接打印方法地址看不到具体方法名,使用(IMP)强转一下


可以观察到

  • 未添加KVO监听的 setAge 方法是-[ZSXPerson setAge:]
  • 添加KVO监听后 setAge 方法是 Foundation_NSSetIntValueAndNotify`
3.2.1 其他数据类型

如果我们还有一个double类型的属性

setHeight方法最终会是_NSSetDoubleValueAndNotify

3.3 查看isa

前面学过isa的指向,我们知道对象方法是存放类对象中的,既然两个对象的setAge对象方法不一样,那是不是他们isa指向的类对象也不一样呢

3.3.1 控制台打印


确实他们isa指向的类对象不是同一个,_person1在这边没有显示类对象名称,_person2可以看出来是ZSXPerson

3.4 使用runtime打印类对象

3.4.1通过runtime打印_person1的类对象:NSKVONotifying_ZSXPerson

3.4.2 打印_person1的类对象的superclass

同时还发现,NSKVONotifying_ZSXPerson的superclass就是ZSXPerson

3.5 结论

添加KVO后

  • 利用RuntimeAPI动态生成一个子类,并且让instance对象的isa指向这个全新的子类NSKVONotifying_ClassName
  • 当修改instance对象的属性时,会调用Foundation的_NSSetXXXValueAndNotify函数

3.6 _NSSetXXXValueAndNotify方法做了什么

_NSSetXXXValueAndNotify是Foundation框架的东西,因为无法拿到Foundation的源码,但是可以通过一些逆向的手段,得到_NSSetXXXValueAndNotify方法实际执行的伪代码

3.6.1 _NSSetXXXValueAndNotify

调用setAge方法时,_NSSetXXXValueAndNotify方法里面做的内容可以认为是这样:

  • [self willChangeValueForKey:@“age”];
  • [super setAge:age];
  • [self didChangeValueForKey:@“age”];
  • didChangeValueForKey 方法会调用监听器的(observeValueForKeyPath:ofObject:change:context:)方法

3.7 NSKVONotifying_ClassName类对象里面还有什么方法

我们遍历打印一下NSKVONotifying_ClassName里面,看看它还有什么方法

- (void)printMethodNameOfClass:(Class)cls {
    unsigned int count;
    // 获得方法数组
    Method *methodList = class_copyMethodList(cls, &count);
    
    // 存储方法名
    NSMutableString *methodNames = [NSMutableString string];
    
    // 遍历所有方法
    for (int i = 0; i < count; i++) {
        // 获得方法
        Method method = methodList[i];
        // 获得方法名
        NSString *methodName = NSStringFromSelector(method_getName(method));
        // 拼接方法明
        [methodNames appendFormat:@"%@", methodName];
        [methodNames appendFormat:@", "];
    }
    
    // 释放
    free(methodList);
    // 打印方法名
    NSLog(@"%@ %@", cls, methodNames);
}

点击屏幕的时候,我们调用一下打印

3.7.1 setAge:

会调用Foundation_NSSetIntValueAndNotify`

3.7.2 class:

你会发现,对象添加KVO监听后,isa只想了一个新的子类NSKVONotifying_ZSXPerson,但是我们在使用[person1 class]获取类对象的时候,返回的依然是ZSXPerson

这是因为:

苹果底层设计时,为了屏蔽内部实现,让开发者使用过程中,不会突然看到一个异常的东西,避免胡思乱想

我们可以认为NSKVONotifying_ZSXPerson类重写了 class 方法如下

- (Class)class {
    return [ZSXPerson class];
}
3.7.2 dealloc:

可以认为里面就是做了一些跟KVO释放有关的收尾操作

  • (void)dealloc {
    // 收尾工作
    }
3.7.2 _isKVOA:

返回是否是KVO的相关类

- (BOOL)_isKVOA {
    return YES;
}

4. 总结

4.1 未使用KVO监听的对象

4.2 使用了KVO监听的对象

4.3 添加KVO后

  • 利用RuntimeAPI动态生成一个子类,并且让instance对象的isa指向这个全新的子类NSKVONotifying_ClassName
  • 当修改instance对象的属性时,会调用Foundation的_NSSetXXXValueAndNotify函数
    • willChangeValueForKey:
    • 父类原来的setter
    • didChangeValueForKey:
      内部会触发监听器(Oberser)的监听方法( observeValueForKeyPath:ofObject:change:context:)

扩展

手动触发KVO

  • 碰过这样一道面试题:使用下划线直接访问成员变量的方式给变量赋值,会不会触发KVO监听?

答案是:不会。因为KVO重写的是set方法(setAge:)。直接给成员变量赋值不会走set方法,因此也不会触发KVO监听

  • 然后又会问,那能不能手动触发KVO监听?
手动触发

只要手动调用实例对象的willChangeValueForKey:和didChangeValueForKey方法,就能触发

注意

需要分别调用willChangeValueForKey:和didChangeValueForKey方法才会触发KVO

  • 内部实现在执行didChangeValueForKey方法的时候,会判断前面是否执行了willChangeValueForKey:方法,前面有调用过才会触发KVO 监听

@oubijiexi

数字孪生通信层开发:C#实现OPC UA到Unity3D的实时数据映射(2026年工业级实战指南) (西门子数字孪生总监):“在产线上,50ms的延迟意味着1%的设备误操作率。2026年,通信层不是‘工具’,是数字孪生的‘生命线’。 阅读详情

相关推荐

足球赛事数据API:开发者生存指南(附真实踩坑记录)

作为一个既爱看球又爱写代码的老宅男,我这些年用过的足球API比看过的比赛还多。从最初被各种API文档折磨到怀疑人生,到现在能闭着眼睛调接口,中间的血泪史够写本书了。今天就把这些经验(和教训)分享给各位同好,特别是那些正在为"老板要做个足球App"而秃头的同行们。文档清晰免费层可用响应格式规范API-Sports免费额度大方支持GraphQL有中文文档(难得!Sportmonks数据全面有Webhook支持按需付费。

Happy0970的博客 2191

iOS开发 - KVO原理及应用场景

KVO(Key-Value Observing)是一种iOS开发中常用的机制,用于监视对象属性的变化,当被观察的对象的属性发生变化时,它会自动通知观察者做出相应的响应。这样,当textObject的text属性发生变化时,观察者的observeValue函数就会被调用,更新UI。KVO的基本概念是:一个对象A监视另一个对象B的属性的变化,并在B的属性发生改变时,向A发送通知,A就可以做出相应的响应。这样,就可以使用KVO监听网络请求,当网络请求中的数据发生改变时,更新界面了。

weixin_38041747的博客 865

Ubuntu关闭更新提醒的三层控制方法:从GUI到APT配置

Linux系统更新机制本质上是包管理器(APT)驱动的自动化运维流程,其核心原理在于分离‘元数据刷新’、‘安全补丁安装’和‘用户通知’三个职能。这种分层设计既保障了基础安全性,又为系统管理员提供了策略定制空间。技术价值体现在提升生产环境稳定性、规避未经验证的内核/驱动升级风险,并支持ROS、Blender渲染、工业控制等对时序敏感的应用场景。本文聚焦Ubuntu系统入门教程中高频需求——科学关闭软件更新提醒,覆盖Ubuntu 20.04及LTS版本的GUI设置、systemd服务禁用与APT配置修改三大实操

weixin_29698641的博客 394

OC:跟随码哥一起学习KVO

当实例对象 Person 的 age 值发生变化,根据实例对象 isa 指针找到对应的类对象,然后调用对应类对象的方法。:KVO的全称是Key-Value Observing,俗称“键值监听”,可以用于监听某个对象属性值的改变。而对象添加KVO处理,肯定是在实现 setAge: 方法的时候,触发了监听器(Oberser)的监听方法。2.1、查看添加KVO时,类对象与元类对象的变化。3.1、未使用KVO监听的对象。3.2、使用了KVO监听的对象。2、调用原来的setter实现。2.3、对比两个类的对象方法。

2501_90256507的博客 1032

从零到一:Halcon手眼标定的实战避坑指南

本文详细解析了Halcon手眼标定的完整流程,重点介绍了Eye-in-Hand和Eye-to-Hand两种模式的实操技巧与常见陷阱。通过九点法、N点法等实战案例,提供硬件配置检查、数据采集策略及误差修正方案,帮助开发者提升机械臂与视觉系统的协同精度,适用于工业自动化领域的精准定位与抓取任务。

neovim7hacker的博客 234

实测对比:纳芯微NSD1624在光伏逆变器中的性能表现(含温度测试数据)

本文详细评测了纳芯微NSD1624非隔离驱动芯片在光伏逆变器中的性能表现,包括动态效率、高温稳定性及抗干扰能力。实测数据显示,该芯片在800V母线电压下效率峰值达99.03%,高温环境下结温稳定在102.7℃,且传播延迟一致性优异。与竞品相比,NSD1624在总损耗和热阻方面具有显著优势,是光伏逆变器驱动方案的理想选择。

weixin_29297127的博客 363

OC中的KVO

看官们,我们在前面章回中介绍了OC中的KVC,本章回中将介绍OC中的KVO。 我们说的KVO是Key Value Observing的缩写,它主要用来监听类属性的变化,它是在NSObject类中实现的,通常情况下我们定义的类只需要继承NSObject类就可以使用KVO来监听类属性的变化。下面是KVO的使用方法: 1.给属性注册监听器 - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)ke...

talk_8的专栏 623

04目标检测-Two-stage的目标检测算法

前面我们对进行了对比分析,同时上一篇我们介绍了传统算法在目标检测的原理和效果,此篇我们记录了我学习目标检测算法的深度,深入讲述一下深度学习算法在目标检测的原理和效果。原文链接:https://blog.youkuaiyun.com/qq_41946216/article/details/132800752。版权声明:本文为优快云博主「爱吃面的猫」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。One-stage(YOLO和SSD系列):直接回归目标位置。

qq_41946216的博客 3650

OC - KVO实现原理

1.KVO简介   KVO是Objective-C对观察者设计模式的一种实现,它提供一种机制,指定一个被观察对象(如A类),当对象中的某个属性发生变化的时候,对象就会接收到通知,并作出相应的处理。在MVC设计架构下的项目,KVO机制很适合实现mode模型和view视图之间的通讯。例如:代码中,在模型类A创建属性数据,在控制器中创建观察者,一旦属性数据发生改变就收到观察者收到通知,通过KVO再在控...

weixin_30462049的博客 287

GT-suite v2016的下载和安装

1 写在前面 GT-suite 是一款用来做内燃机仿真的软件。在安装过程中遇到很多问题,网上的安装教程也大都抄来抄去,试着安装了几遍都没有成功。最终在贴吧一个老哥的帖子里找到了解决办法,但是老哥的帖子也不是很详细,所以做了这个详细版本的教程。 GT-suite v2016安装包: 链接:https://pan.baidu.com/s/1JZPgJ8_-J-L8rV84-eHedQ 提取码:uj...

kisssshot的博客 3万+

使用MeshLab高效对齐3D模型:从OBJ导入到坐标修正全流程

本文详细介绍了使用MeshLab高效对齐3D模型的全流程,涵盖从OBJ导入、坐标修正到最终导出的核心步骤。通过将模型中心归位至坐标原点,并利用主轴对齐功能快速摆正模型,为后续的3D打印、体素化等处理奠定精确的几何基础。

weixin_29313423的博客 92

OC中的KVC与KVO

到目前为止,可以通过存取方法,属性或直接设置实例变量来直接更改对象状态。也可以通过字符串描述来更改对象状态,这种方式称为键值编码(KVO)。KVC提供了一种运行时而非编译时动态访问对象属性与实例变量的方式。 KVC的基本用法 setValue:(要设置的值)forKey:(键,对象的属性名称或者实例变量名称),用来设置实例变量的值。 valueForKey:(对象的属性名称或者

小白的逆袭~ 486

matlab 一维相位解缠

一维相位解缠算法的matlab代码实现。

点云侠的博客 372

ios 通过kvc修改属性会触发kvo_OC底层原理探究:OC对象本质、KVO/KVC

1.一个NSObject对象占用多少内存?16个字节系统分配了16个字节给NSObject对象(通过malloc_size函数获得)但NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过class_getInstanceSize函数获得)NSObject对象的本质就是结构体。// NSObject的底层实现 @interface NSObject { Class isa;...

weixin_39849127的博客 137

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

【OC学习-32】KVO-用一个对象监控另一个对象的属性,如有变化,则输出需要的结果

KVO应该是key-value-observer,意思就是键值观察。作用就是用一个对象A监测对象B,如果对象B属性发生变化,那么就会发送一个消息给对象A,这样……呃,就这样了。至于拿到通知后怎么处理,那是后话。

小小的客栈 大大的江湖 2086

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

OC语法

一、OC本质 模拟器(i386)、32bit(armv7)、64bit(arm64) 查看C语言实现的指令 不包含__weak关键字 xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m ...

chuoyi2983的博客 253

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

【IOS 开发学习总结-OC-14】★★★objective-c面向对象之——KVO(键值监听)

KVO:键值监听,全称 keyValueObserving,是观察者模式的一种。NSKeyValueObserving协议为 KVO提供支持。NSObject 遵守了该协议,因此NSObject的子类(所有 oc 类都是NSObject的子类)都可以使用该协议中的方法。监听器的一些常用方法下面是关于监听器的一些常用方法: 方法名 用途 addObserver: forKeyPath: op

Albert的专栏 846

【OC学习-34】通知NSNotification,类似于KVO,用于对象之间监听然后发通知提醒

通知其实和KVO类似,就是先在类A中设置通知,然后再类B中设置个监听这个通知的方法,当然可以通过这个通知方法可以传递一些参数,得到这个参数之后,一般是触发一个动作,此处举例就是触发输出一些内容而已。

小小的客栈 大大的江湖 2218

KVO模式 ———满足猥琐大众的 偷窥模式

KVO模式浅谈-满足猥琐男的偷窥模式马仔哥KVO模式 Key-Value Observing 它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。KVO其实也是“观察者”设计模式的一种应用。我的看法是,这种模式有利于两个类间的解耦合,尤其是对于 业务逻辑与视图控制 这两个功能的解耦合。我自己的看法:我

maxingzehaoren的博客 2486

iOS OC基础知识笔记

iOS OC基础知识笔记 一个NSObject对象占用多少内存? 系统分配了16个字节给NSObject对象(通过malloc_size函数获得) 但NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过class_getInstanceSize函数获得) #import <objc/runtime.h> #import <malloc/malloc.h&...

WJ的博客 1484

KVO 底层原理深度解析:为什么监听后对象的 isa 会变?

KVO 实现机制分析:当添加 KVO 监听时,Runtime 会动态生成名为 NSKVONotifying_ClassName 的子类,并将被观察对象的 isa 指针指向该子类。这个子类重写了原类的 setter 方法,在属性修改前后插入通知逻辑。通过改变 isa 指针,KVO 实现了对属性变化的自动监听,同时保持对原类的透明性。移除观察者后,isa 指针会恢复指向原类。

Sheffi 1057

iOS底层学习——KVO

文章目录使用底层原理 使用 /// 创建Person类 @interface DDPerson : NSObject @property (nonatomic, assign) int age; @end 底层原理 当我们创建

Meet的博客 371

Object-C底层原理总结

Object-C-底层原理一.对象的本质二.isa superclass 指针.isa superclass 指针三.kvo分析功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 一.对象的本质 OC的类主要C\C++的机构体来实现

weixin_42580612的博客 2885

iOS底层原理班(下)/OC对象/关联对象/多线程/内存管理/性能优化-李明杰-专题视频课程...

得遇名师,突飞猛进!iOS培训王者MJ(李明杰)老师精心研发,iOS进阶课程,实用技术不断的更新和升级,更快帮助职场人士在开发领域脱颖而出。远程视频教学,无须长途奔袭,碎片化时间学习,成长随时随地!...

seemygo的博客 1996

iOS底层原理系列02-深入了解Objective-C

对于自定义类,其内存结构会更复杂,包含从父类继承的变量和自己声明的变量。int _age;@end包含从NSObject继承的isa指针(8字节)包含一个int类型变量_age(4字节)包含一个double类型变量_height(8字节)包含一个NSString*类型的_name指针(由于@property自动合成,8字节)理论上总大小为:8 + 4 + 8 + 8 = 28字节。但实际分配会考虑内存对齐,可能会是32字节。特性+load调用时机程序启动加载类和分类时。

但行好事,莫问前程;不忘初心,方得始终! 3208

KVO 通知 代理

KVO 1、注册观察者 [A addObserver:B …] A 被观察者 B 观察者 2、keyPath相同时,会调用observeValueForKeyPath:ofObject:change:context:方法 吗? get,set 3、addObserver removeObserver 对应数目 通知 1、特性 KVO 通知 代理 1、哪些情况使用 ...

weixin_43900761的博客 302
上一篇: OC对象 - isa指针和supperClass
下一篇: OC对象 - KVC
aiousee
博客等级 码龄14年 540粉丝 45原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值