OC_KVC与KVO简单介绍

KVC

KVC概述

KVCKey-value coding 键值编码,是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值。

KVC案例

@interface Person : NSObject@property (nonatomic,assign) int age;
@property (nonatomic,copy) NSString *name;@end
复制代码

如以上代码,我们创建了一个 Person 类,他有两个属性,分别是 agename。 然后我们将其实例化,并且赋予其姓名和年龄属性:

Person *p1 =[Person new];
p1.name = @"Kobe";
p1.age = 30;
复制代码

这是常规的赋值方式,那么KVC是如何赋值的呢?

[p1 setValue:@"Kobe" forKey:@"name"];
[p1 setValue:@"38" forKey:@"age"];
复制代码

如以上代码,通过KVC,我们可以直接使用键值对的方式对对象的属性进行赋值。

同理,获取属性也可以使用键值对的方式:

[p1 valueForKey: @"name"];
[p1 valueForKey:@"age"];
复制代码

这样即可获取对象的 nameage属性。


那么给我们再设置一个 Dog

@interface Dog : NSObject
@property (nonatomic,copy) NSString *name;
@end
复制代码

Person 类增加一个 Dog 属性

@property (nonatomic,strong) Dog *dog;
复制代码

实例化 Dog 对象并初始化,然后赋值给 Person 对象

Dog *dog1 = [Dog new];
dog1.name = @"旺财";
p1.dog = dog1;
复制代码

那么如何使用KVC给获取 p1dogname 属性呢? 只需要嵌套一层:

// 获取
[[p1 valueForKey:@"dog"] valueForKey:@"name"];
// 设置
[[p1 valueForKey:@"dog"] setValue:@"狗狗" forKey:@"name"];
复制代码

还有一种简洁的方法就是使用以下方法

// 设置
[p1 setValue:@"狗狗" forKeyPath:@"dog.name"];
// 获取
[p1 valueForKeyPath:@"dog.name"];
复制代码

直接使用 "." 连接属性即可。

KVO

KVO 即 Key-Value Observing 是基于 KVC 的一种观察者模式,它可以通过 KVC 的方式对对象的属性观测,当 keyPath 的值变化时会发出通知。

KVO的实现方法

KVO的实现是以下三个步骤:

  • 向通知中心注册观察
  • 在某一时刻 keyPath 的值变化,通知中心向观察者发送消息,调用方法。
  • 重写 dealloc 方法,注销观察。

KVO的案例

首先我们先创建一个类用于数值变化,这里就叫 KVOItem 类,给它添加一个 int 类型属性 number

@interface KVOItem : NSObject
@property (nonatomic,assign) int number;
@end
复制代码

然后创建并初始化对象,并为其添加观察:

item = [KVOItem new];
item.number = 0;
[item addObserver:self forKeyPath:@"number" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:@"KVOTEST"];
复制代码

这里观察 itemkey 值为 number 的属性。 注册观察后,需要实现观察所调用的方法

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{if (context == @"KVOTEST") {NSLog(@"change from %@ to %@",[change valueForKey:@"old"],[change valueForKey:@"new"]);}
}
复制代码

然后我们使用一个 NSTimer 来重复更改 itemnumber 属性。

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3 repeats:YES block:^(NSTimer *timer){item.number++;}];[timer fire];
复制代码

并且不要忘了在 dealloc 方法中注销观察:

-(void)dealloc{[item removeObserver:self forKeyPath:@"KVOTEST"];
}
复制代码

运行后我们可以看到在控制台打印以下消息:

change from 0 to 1
change from 1 to 2
change from 2 to 3
change from 3 to 4
复制代码

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

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

相关文章

C语言100例01 PHP版(练习)

题目&#xff1a;有1、2、3、4个数字&#xff0c;能组成多少个互不相同且无重复数字的三位数&#xff1f;都是多少&#xff1f; 程序分析&#xff1a;可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。 代码&#xff1a; 1 for($i1;$i&l…

嵌入式根文件系统制作

1:文件系统分类&#xff1a; 基于flash的文件系统&#xff1a;flash有两种&#xff0c;一种是NOR,另一种NAND。NOR型 FLASH主要用于存放程序。NAND型 FLASH主要用于存放数据。NOR的特点是可在芯片内执行。这样应用程序可以直接在flash内存内运行&#xff0c;不必再把代码读到…

跨时钟域电路设计——结绳法

信号从快时钟域到慢时钟域过渡时&#xff0c;慢时钟可能无法对快时钟变化太快的信号进行采样。 之前的同步器法对两个时钟间的关系有要求&#xff0c;结绳法适用于任何时钟域之间的过渡。 结绳法的原理是将快时钟信号的脉冲周期延长&#xff0c;等到慢时钟周期采样后再“解绳”…

我之理解---计时器setTimeout 和clearTimeout

今天在写个图片切换的问题 有动画滞后的问题&#xff0c;才动手去查setTimeout 和clearTimeout。之前写的图片播放器也有类似的问题&#xff0c;有自动start按钮 和stop按钮&#xff0c; 其他都正常&#xff0c;问题出在每次多次快速的点击start按钮时&#xff0c;图片播放的速…

002服务提供者Eureka

1、POM配置 和普通Spring Boot工程相比&#xff0c;仅仅添加了Eureka、Spring Boot Starter Actuator依赖和Spring Cloud依赖管理 <dependencies><!--添加Eureka Server依赖--><dependency><groupId>org.springframework.cloud</groupId><art…

使用Busybox构造cramfs根文件系统

使用Busybox构造cramfs根文件系统 11.1、下载Busybox&#xff0c;如果系统中没有mkcramfs工具则还要下载mkcramfs压缩工具。本文件系统使用Busybox-1.10.1&#xff0c;cramfs-1.1。压缩文件Busybox-1.10.1.tar.bz2&#xff0c;cramfs-1.1.tar.gz。 22.解压文件&#xff1a; tar…

关于二维码分块上色(彩色二维码)的算法研究

原文:关于二维码分块上色&#xff08;彩色二维码&#xff09;的算法研究众所周知&#xff0c;二维码通常是黑白的&#xff0c;而且是由若干个长方形或正方形小块平铺而成。但从人们的审美角度来看&#xff0c;常见的黑白二维码不免让人审美疲劳。本文试着从分块上色的角度对二维…

20145309信息安全系统设计基础第12周学习总结后篇

指针与声明 声明 1、C语言中变量的声明 类型&#xff08;type&#xff09; 声明符&#xff08;declarator&#xff09; 2、最简单的声明是变量 3、指针数组 指针数组是一个数组数组里的元素都是指针例&#xff1a;int *daytab[13]4、数组指针 数组指针是一个指针指针指向一个类…

跨时钟域电路设计——多bit信号FIFO

多个bit信号的跨时钟域仅仅通过简单的同步器同步时不安全的。 如下图&#xff1a; 虽然信号都同步到目的时钟域&#xff0c;可完成的功能却与设计的初衷不相符。 解决方案之一为对信号进行格雷码编码&#xff0c;但此方案只适用于连续变化的信号。另一种方案为增加新的控制信号…

嵌入式linux系统中设备驱动程序

嵌入式linux系统中设备驱动程序是内核的一部分&#xff0c;完成对设备初始、读写操作和控制等功能。驱动程序隐藏了硬件设备的具体细节&#xff0c;对不同的设备提供一致的接口&#xff0c;这些接口通过file_Operation结构来定义&#xff0c;设计驱动程序的大部分工作就是根据硬…

WPF 打印实例

原文:WPF 打印实例在WPF 中可以通过PrintDialog 类方便的实现应用程序打印功能&#xff0c;本文将使用一个简单实例进行演示。首先在VS中编辑一个图形&#xff08;如下图所示&#xff09;。 将需要打印的内容放入同一个<Canvas>中&#xff0c;并起名为“printArea”&…

mongodb 物理删除数据

刚开始用mongodb的时候&#xff0c;感觉很好用&#xff0c;速度很快&#xff0c;不过后面就遇到一个问题&#xff0c;数据物理内存一直增加&#xff0c;删除表也不管用。 然后网上找了各种办法&#xff0c;最后发现一个办法管用&#xff0c;就是物理删除存储数据。 操作如下&am…

计数排序、桶排序和基数排序

计数排序 当输入的元素是 n 个 0 到 k 之间的整数时&#xff0c;它的运行时间是 Θ(n k)。计数排序不是比较排序&#xff0c;排序的速度快于任何比较排序算法。 由于用来计数的数组C的长度取决于待排序数组中数据的范围&#xff08;等于待排序数组的最大值与最小值的差加上1&a…

静态时序分析——基础概念

一、简述 静态时序分析是检查系统时序是否满足要求的主要手段。以往时序的验证依赖于仿真&#xff0c;采用仿真的方法&#xff0c;覆盖率跟所施加的激励有关&#xff0c;有些时序违例会被忽略。此外&#xff0c;仿真方法效率非常的低&#xff0c;会大大延长产品的开发周期。静…

linux framebuffer 例子

昨天做的一个极简单的framebuffer的例子&#xff0c;用来学习怎样操作fb设备。 这段代码是在picogl的vesafb backend部分的基础上简出来的&#xff0c;所以变量名还保留着。 流程如下&#xff1a; &#xff11; 打开framebuffer设备&#xff1b; &#xff12; 通过ioctl取得f…

加载数据时,页面显示正在加载的动画,支持移动端

最近在使用ionic3做一个移动端APP&#xff0c;在用户网络环境差的时候&#xff0c;查询数据会比较慢&#xff0c;这个时候需要模拟其他成熟的APP给页面上加入一个加载的动画。由于一开始我不知道ionic3本身已经提供了一套组件&#xff0c;所以自己先做了一套样式。提供给不用框…

静态时序分析——单周期

一、建立时间的检查 建立时间的检查是指检查电路里每一个触发器的数据和时钟的关系是否满足建立时间的要求。 我们以上图为例进行建立时间检查。由图可知&#xff0c;我们主要针对第二个触发器UFF1进行检查。我们可以梳理时序关系如下&#xff1a; 通过这个图&#xff0c;我们…

自己搭建的CISCO实验环境

交换机&#xff1a;设备型号&#xff1a; CISCO 3750 24-TS 3台CISCO 3750 48-PS 1台路由器&#xff1a;设备型号&#xff1a;1.CISCO 2821 3台2.CISCO 3745 3台 物理拓扑图如下&#xff1a; 转载于:https://blog.51cto.com/zxs3026/2156424

关于大数定律的讨论(转)

科普一下所谓“大数定律的四种证法” 作者 : 王若度最近网上总是调侃数学、统计博士知道所谓“大数定律的四种证法”&#xff0c;本身是模仿《孔乙己》的桥段&#xff0c;用以调侃数学、统计博士学一些没什么用的东西。其实我是从来没听说过大数定律的四种证法这回事的&#x…

DM365 u-boot 启动分析

第一阶段&#xff1a;汇编语言启动 先看u-boot/board/davinci/dm365_ipnc/下的文件。 u-boot.lds OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . 0x0000000…