Objective-C 学习笔记 | KVO(key-value obsereving)

news2024/10/6 14:33:19

Objective-C 学习笔记 | KVO(key-value obsereving)

  • Objective-C 学习笔记 | KVO(key-value obsereving)
    • 使用 KVO
    • KVO 的工作原理

Objective-C 学习笔记 | KVO(key-value obsereving)

KVO 是指当指定的对象的属性被修改时,允许对象接收通知的机制。

使用 KVO

创建一个 BNRObserver,实现 lastTime 发生变化时的回调方法:

#import "BNRObserver.h"

@implementation BNRObserver

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    NSString *oldValue = [change objectForKey:NSKeyValueChangeOldKey];
    NSString *newValue = [change objectForKey:NSKeyValueChangeNewKey];
    NSLog(@"Observed: %@ of %@ was changed from %@ to %@", keyPath, object, oldValue, newValue);
}

@end

在 main.m 中创建一个 BNRObserver 实例,让它观察 logger 的 lastTime 属性:

__unused BNRObserver *observer = [[BNRObserver alloc] init];
// 一旦 logger 的 lastTime 发生变化,通知 observer 改变的新值和之前的旧值
[logger addObserver:observer forKeyPath:@"lastTime"
    options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

如果使用存取方法来设置属性,那么系统会自动通知观察者,上述方法有效。

如果直接给实例变量赋值,可以通过 willChangeValueForKey: 和 didChangeValueForKey: 方法显式通知系统某个属性的值即将/已经改变。

// 动作方法总有一个实参,它是传入发送动作消息的对象
- (void)updateLastTime:(NSTimer *)timer
{
    NSDate *now = [NSDate date];
    // [self setLastTime:now];
    [self willChangeValueForKey:@"lastTime"];
    _lastTime = now;
    [self didChangeValueForKey:@"lastTime"];
    NSLog(@"Just set time to %@", self.lastTimeString);
}

如果不观察 _lastTime,而是观察 _lastTimeString,我们可以实现一个类方法,告诉系统 _lastTime 会影响 _lastTimeString:

// 类方法的名称 = keyPathsForValuesAffecting + 首字母大写的键的名称(LastTimeString)
+ (NSSet *)keyPathsForValuesAffectingLastTimeString
{
    return [NSSet setWithObject:@"lastTime"];
}

KVO 的工作原理

运行时,如果向某个对象发送 addObserver:forKeyPath:options:context: 方法,它会完成下面三件事:

  1. 决定被观察对象的类,并使用 objc_allocateClassPair() 函数给这个类定义一个新的子类。
  2. 改变对象的 isa 指针,让它指向新的子类(高效改变对象的类型)。
  3. 覆盖被观察对象的存取器,发送 KVO 消息。

请添加图片描述

例如,一个类的 location 属性的存方法代码如下:

// BNRTowel
- (void)setLocation:(NSPoint)location
{
    _location = location;
}

在新的子类中,该方法会被覆盖为:

// KVONotifying_BNRTowel
- (void)setLocation:(NSPoint)location
{
    [self willChangeValueForKey:@"location"];
    [super setLocation:location];
    [self didChangeValueForKey:@"location"];
}

子类的存取器实现会调用原始类的实现,然后将它们用简明的 KVO 通知消息封装起来。这些新的类以及方法都会在运行时使用 Objective-C 运行时函数定义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1834443.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何掌握 Java 中的国际化和本地化

随着全球化的发展&#xff0c;软件开发不仅要满足本地用户的需求&#xff0c;还要满足全球用户的需求。因此&#xff0c;软件的国际化&#xff08;Internationalization&#xff0c;I18N&#xff09;和本地化&#xff08;Localization&#xff0c;L10N&#xff09;显得尤为重要…

为什么网上这么多破解 Intellij IDEA 的工具,但是官方却不管呢?

大家好&#xff0c;我是小2&#xff0c;一个程序员~ 程序员小2 每天一篇技术重磅好文&#xff0c;涉及一线互联网大厂应用架构&#xff08;高可用、高性能、高稳定&#xff09;&#xff0c;AI、大数据、java架构等热门领域。 112篇原创内容 公众号 来源&#xff1a;Java知音…

【代码随想录——动态规划——第五周】

1.单词拆分 func wordBreak(s string, wordDict []string) bool {n : len(s)dp : make([]bool, n1)dp[0] truefor j : 0; j < len(wordDict); j {if len(wordDict[j]) > n {continue}if wordDict[j] s[:len(wordDict[j])] {dp[len(wordDict[j])] true}}//fmt.Println(…

Facebook与地方文化:数字平台的多元表达

在当今数字化时代&#xff0c;社交媒体不仅仅是人们交流的工具&#xff0c;更是促进地方文化传播和表达的重要平台。作为全球最大的社交网络之一&#xff0c;Facebook在连接世界各地用户的同时&#xff0c;也成为了地方文化多元表达的重要舞台。本文将深入探讨Facebook如何通过…

简单通用防篡改水印组件封装(vue3)

一、项目结构 二、项目代码 1.App.vue <template><div class"container"><Watermark text"版权所有"><div class"content"></div></Watermark><Watermark text"禁止转载" style"backgr…

【MongoDB 新搭档 Kafka】

对于做过数据处理&#xff0c;使用过消息队列的小伙伴 &#xff0c;Kafka可以算是老朋友了&#xff0c;但是最近一个场景下&#xff0c;新的用法&#xff0c;让其变为了MongoDB的新搭档。 开始 从一个问题开始&#xff0c;熟悉MongoDB的小伙伴&#xff0c;可能使用过changeSt…

消息队列-Rabbit运行机制

Producer(生产者) 和 Consumer(消费者) Producer(生产者) :生产消息的一方&#xff08;邮件投递者&#xff09;Consumer(消费者) :消费消息的一方&#xff08;邮件收件人&#xff09; 消息一般由 2 部分组成&#xff1a;消息头&#xff08;或者说是标签 Label&#xff09;和 …

ABAP程序示例:如何用ABAP显示图形?

在SAP ERP 系统中&#xff0c;对于用户来说&#xff0c;一般都是用ABAP来开发自己报表或事务&#xff0c;用WRITE输出报表或用ALV来显示报表。可否将报表中的相关数据用类似如下图形来显示呢&#xff1f; 以下为示例代码&#xff1a; REPORT ZPR_GRAPHS.DATA: BEGIN OF ITAB_…

每日AI资讯-20240617

1. Meta AI的NLLB-200登上Nature Meta AI在社交媒体X上宣传自家的大模型NLLB&#xff0c;全称为No Language Left Behind&#xff0c;这个AI模型能够翻译200种语言&#xff0c;包括资源匮乏的语言&#xff0c;更难得的是&#xff0c;NLLB模型可以免费提供给非商业用途。 这项研…

PostgreSQL源码分析——initdb

数据库初始化 在安装完数据库后&#xff0c;需要进行初始化数据库操作&#xff0c;对应PostgreSQL数据库中就是需要进行initdb后&#xff0c;才能对数据库进行启动。initdb的过程&#xff0c;其实就是创建数据库实例的过程&#xff0c;生成模板数据库和相应的目录、文件信息&a…

一文读懂-Linux用户和权限

前言 最近换了台公司配的电脑&#xff0c;我的电脑本来就快坏了&#xff0c;结果放家里的门上挂着&#xff0c;pia的一下&#xff0c;摔了&#xff0c;a壳和b壳直接分离掉了&#xff08;还好公司给配的电脑配置挺高的&#xff09;&#xff0c; 仔细回顾了一下&#xff0c;已经…

Spring Cloud 专题-前言篇(1)

引言 随着微服务架构的兴起&#xff0c;Spring Cloud 作为一套基于 Spring Boot 实现的云应用开发工具集&#xff0c;为开发者提供了在分布式系统&#xff08;如配置管理、服务发现、断路器、智能路由、微代理、控制总线等&#xff09;中快速构建一些常见模式的能力。本篇文档…

HTTP 415错误状态码

HTTP 415错误状态码是指"Unsupported Media Type"&#xff08;不支持的媒体类型&#xff09;。这通常发生在客户端向服务器发送请求时&#xff0c;请求中包含的媒体类型&#xff08;例如Content-Type头部&#xff09;不被服务器支持或识别的情况下。 解决方法&#…

【Linux】进程间通信3——system V进程间通信

1.system V进程间通信 管道通信本质是基于文件的&#xff0c;也就是说操作系统并没有为此做过多的设计工作&#xff0c;而system V IPC是操作系统特地设计的一种通信方式。但是不管怎么样&#xff0c;它们的本质都是一样的&#xff0c;都是在想尽办法让不同的进程看到同一份由操…

哪个充电宝牌子好用又实惠?盘点四大平价充电宝分享

在当今快节奏的生活中&#xff0c;充电宝已成为我们日常生活中不可或缺的一部分。然而&#xff0c;面对市场上琳琅满目的充电宝品牌和型号&#xff0c;许多消费者误以为选择容量越大、价格越高的充电宝就是最好的选择。实际上&#xff0c;买充电宝并不是一味追求高容量和高价格…

首批50辆苏州金龙纯电大巴交付!武汉通勤客运绿色发展提质升级

随着第一缕阳光跃上黄鹤楼的飞檐&#xff0c;城市逐渐苏醒。在车水马龙中&#xff0c;一辆辆通勤班车穿梭其中&#xff0c;确保通勤保障单位人员的安全出行。而这其中就有武汉市雄翔通勤汽车运输有限公司&#xff08;以下简称“武汉雄翔”&#xff09;的身影。 5月底&#xff…

MySQL数据库与基本操作(增删改查)

一、数据库的基本概念 数据库要学习的四个基本概念&#xff0c;主要是&#xff1a;数据、数据库系统、数据库、数据管理系统。数据&#xff08;Date&#xff09;是描述事物的记录&#xff0c;数据库系统&#xff08;DBS&#xff09;&#xff0c;数据库管理系统&#xff08;DBMS…

大学物理(动量定理)

目录 冲量与动量 质点动量定理 质点系动量定理:​编辑 例题 ​编辑 例题 ​编辑 动量守恒定律:。 例题 ​编辑 例题 ​编辑 角动量 ​编辑 例题 ​编辑 力矩与角动量定理​编辑 角动量守恒定律: ​编辑 例题 冲量与动量 质点动量定理 质点系动量定理: 例题 例…

Java的三个接口Comparable,Comparator,Cloneable(浅拷贝与深拷贝)

Comparable 当我们要进行对象的比较的时候&#xff0c;我们是不能直接用>、< 这些符号直接进行比较的。 由于这是引用类型变量也是自定义类型变量&#xff0c;直接进行比较的时候&#xff0c;我们是通过对象的地址进行比较的&#xff0c;我们可以使用、! 进行两个对象的…

用这个神级提示词插件,能让你的AI绘画工具Stable diffusion提示词直接写中文!

大家好&#xff0c;我是设计师阿威 最近&#xff0c;有同学在使用AI绘画工具 Stable Diffusion的时候和我说&#xff1a;老师&#xff0c;我英文不好&#xff0c;能不能直接让我写中文提示词啊&#xff1f;最好可以直接在SD的输入框就能直接写中文&#xff0c;不用切换网页或者…