KVC 与 KVO

一、Key-Value Coding (KVC)键值编码

 

KVC,即是指 NSKeyValueCoding,一个非正式的 Protocol,提供一种机制来间接访问对象的属性。KVO 就是基于 KVC 实现的关键技术之一。

一个对象拥有某些属性。比如说,一个 Person 对象有一个 name 和一个 age 属性。以 KVC 说法,Person 对象分别有一个 value 对应他的 name 和 age 的 key。 key 只是一个字符串,它对应的值可以是任意类型的对象。从最基础的层次上看,KVC 有两个方法:一个是设置 key 的值,另一个是获取 key 的值。如下面的例子:

 // using the KVC accessor (getter) method-valueForKeNSString *personlName = [p valueForKey:@"name"];// using the KVC  accessor (setter) method.-setValue: forKey:[p setValue:newName forKey:@"name"];

现在,如果 Person 有另外一个 key 配偶(spouse),spouse 的 key 值是另一个 Person 对象,用 KVC 可以这样写:

   // just using the accessor again, same as example aboveNSString *personsName = [p valueForKey:@"name"];// this line is different, because it is using// a "key path" instead of a normal "key"NSString *spousesName = [p valueForKeyPath:@"spouse.name"];
valueForKey 与 valueForKeyPath 要区分开来,valueForKey 可以从一个对象中获取值,而valueForKeyPath可以将多个 key 用点号 “.” 分割连接起来,比如:
[p valueForKeyPath:@"spouse.name"];等同于[[p valueForKey:@"spouse"] valueForKey:@"name"];

二、Key-Value Observing (KVO)键值观察

 

Key-Value Observing (KVO) 建立在 KVC 之上,它能够观察一个对象的 KVC key path 值的变化。举个例子,用代码观察一个 person 对象的 age 变化,以下是实现的三个方法:

 

  • watchPersonForChangeOfAddress: 实现观察
  • observeValueForKeyPath:ofObject:change:context: 在被观察的 key path 的值变化时调用。
  • dealloc 停止观察
    static NSString *const KVO_CONTEXT_ADDRESS_CHANGED = @"KVO_CONTEXT_ADDRESS_CHANGED"@implementation PersonWatcher-(void) watchPersonForChangeOfAddress:(Person *)p
    {// this begins the observing添加键值监听事件
        [p addObserver:selfforKeyPath:@"address"options:0context:KVO_CONTEXT_ADDRESS_CHANGED];// keep a record of all the people being observed,// because we need to stop observing them in dealloc
        [m_observedPeople addObject:p];
    }// whenever an observed key path changes, this method will be called
    - (void)observeValueForKeyPath:(NSString *)keyPathofObject:(id)objectchange:(NSDictionary *)changecontext:(void *)context{// use the context to make sure this is a change in the address,// because we may also be observing other things-键值改变时对应的操作if(context == KVO_CONTEXT_ADDRESS_CHANGED) {NSString *name = [object valueForKey:@"name"];NSString *address = [object valueForKey:@"address"];NSLog(@"%@ has a new address: %@", name, address);}
    }-(void) dealloc;
    {// must stop observing everything before this object is// deallocated, otherwise it will cause crashes-在销毁的时候移除键值监听for(Person *p in m_observedPeople){[p removeObserver:self forKeyPath:@"address"];}[m_observedPeople release];m_observedPeople = nil;[super dealloc];}

    这就是 KVO 的作用,它通过 key path 观察对象的值,当值发生变化的时候会收到通知。

 

转载于:https://www.cnblogs.com/xiaobaichangan/p/5622937.html

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

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

相关文章

使用模拟的单元测试–测试技术5

我的最后一个博客是有关测试代码方法的一系列博客中的第四篇,演示了如何创建使用存根对象隔离测试对象的单元测试。 今天的博客探讨了有时被视为对立的技术:使用模拟对象进行单元测试。 同样,我使用了从数据库检索地址的简单方案:…

多线程中的volatile和伪共享

伪共享 false sharing,顾名思义,“伪共享”就是“其实不是共享”。那什么是“共享”?多CPU同时访问同一块内存区域就是“共享”,就会产生冲突,需要控制协议来协调访问。会引起“共享”的最小内存区域大小就是一个cache…

C语言代码规范(一)缩进与换行

一、缩进的空格数为4个。最好配置代码编辑器将TAB键设置为空格替换&#xff0c;避免出现另一个编辑器打开时格式变乱的情况。 例如Notepad设置 KEIL设置 二、“{” 和 “}”各自独占一行。 不规范例子&#xff1a; for(i 0; i < student_num; i) { if((score[i] > 0…

armv7 cortex a系列编程手册_AWTK能为现代GUI编程带来何种改变?

AWTK是一个伸缩性极强的嵌入式图形框架&#xff0c;它的诞生会给GUI编程研发工程师带来哪些改变&#xff1f;AWTK是一个伸缩性极强的嵌入式图形框架&#xff0c;可在Cortex-M3这样低端的单片机上运行&#xff0c;也可以在Cortex-A7/A8/A9等处理器&#xff0c;甚至DSP以及X86处理…

【转】各种概念POJO、JAVABEAN、DAO、DTO、PO、VO、BO、SSH、EJB

POJO&#xff08;pure old java object&#xff09; 是普通java类&#xff0c;有一些private的参数作为对象的属性&#xff0c;然后针对每一个参数定义get和set方法访问的接口。我看到这个定义&#xff0c;心里就有个疑问了&#xff0c;这个POJO跟JavaBean的定义怎么就这么像&a…

为什么要编写单元测试–测试技巧8

我对最近在“您应该测试什么”上的博客有很多反应&#xff0c;有些人出于各种原因同意我的想法&#xff0c;另一些人则认为建议某些类可能不需要单元测试是非常危险的。 已经处理了什么测试&#xff0c;今天的博客涉及为什么要编写单元测试&#xff0c;而今天的示例代码是基于一…

Git迁移 从SVN到Git

Migrating from SVN to Git 首先我们需要在Stach或者GitHub上新建一个Repository, 拿到它的URL。 接下来参照如下步骤 : At first we should create a new git repository at Stash and get the repository URL, and then follow below steps: 1. 切换到本地git工作目录 chang…

C语言代码规范(二)空格

一、逗号, 之后加空格 printf("error! score[%d] %d\n", i, score[i]); 二、分号; 之后加空格 for(i 0; i < student_num; i) 三、关系运算符<、<、>、>、、! 前后加空格 if( (score[i] > 0) && (score[i] < 100) ) 四、赋值运算符…

c++ 多重背包状态转移方程_动态规划入门——详解经典问题零一背包

本文始发于个人公众号&#xff1a;TechFlow&#xff0c;原创不易&#xff0c;求个关注今天是周三算法与数据结构专题的第12篇文章&#xff0c;动态规划之零一背包问题。在之前的文章当中&#xff0c;我们一起探讨了二分、贪心、排序和搜索算法&#xff0c;今天我们来看另一个非…

Discuz! 的编码规范

前言 本规范由编程原则组成&#xff0c;融合并提炼了开发人员长时间积累下来的成熟经验&#xff0c;意在帮助形成良好一致的编程风格。适用范围 如无特殊说明&#xff0c;以下规则要求完全适用于Discuz!项目&#xff0c;同时也可大部分适用于COMSENZ旗下其他PHP项目。标准化的重…

C语言代码规范(三)if语句

一、整型变量与0比较 许多人为了一时之便&#xff0c;模仿布尔变量风格写为如下代码 if(value) {... }if(!value) {... } 应当用 或 ! 来与0比较 if(0 value) {... }if(0 ! value) {... } 二、当if内的语句是与常量进行比较时&#xff0c;常量为左值&#xff0c;变量为右…

6月24 面向对象的设计原则-----工厂模式和单列模式

工厂模式&#xff1a; 工厂模式就是专门负责将大量有共同接口的类实例化&#xff0c;而且不必事先知道每次是要实例化哪一个类的模式。它定义一个用于创建对象的接口&#xff0c;由子类决定实例化哪一个类。 工厂模式相当于创建实例对象的new&#xff0c;经常要根据类Class生成…

LeetCode Subsets

原题链接在这里&#xff1a;https://leetcode.com/problems/subsets/ 题目&#xff1a; Given a set of distinct integers, nums, return all possible subsets. Note: Elements in a subset must be in non-descending order.The solution set must not contain duplicate su…

使用ThreadPoolExecutor并行化独立的单线程任务

Java SE 5.0中引入的任务执行框架是简化多线程应用程序的设计和开发的巨大飞跃。 该框架提供了用于管理任务概念&#xff0c;管理线程生命周期及其执行策略的工具。 在此博客文章中&#xff0c;我们将描述该框架的功能&#xff0c;灵活性和简单性&#xff0c;以展示一个简单的用…

python定义一个圆_Python-矩形和圆形

原博文 2019-11-11 12:34 − Exercise 15.1. 定义一个叫做Circle 类&#xff0c;类的属性是圆心 (center) 和半径 (radius) , 其中&#xff0c;圆心 (center) 是一个 Point 类&#xff0c;而半径 (radius) 是一个数字。 实例化一个圆心 (center) 为 (150, 100) &#xff0c;半…

C语言代码规范(四)命名规则

一、宏定义全部字母大写&#xff0c;单词间下划线间隔 #define FLASH_PAGE_SIZE 256 #define FLASH_SECTOR_SIZE (4 * 1024) #define FLASH_BLOCK_SIZE (64 * 1024) #define FLASH_SIZE (16 * 1024 * 1024) 二、const修饰的常量全部字母大写&#xff0c;单词间…

Forbidden You don't have permission to access / on this server PHP

Forbidden You dont have permission to access / on this server PHP 在新安装的谷歌游览器里&#xff0c;打不了PHP网站了&#xff0c;错误显示&#xff1a; Forbidden You dont have permission to access / on this server. 原因还是配置权限问题 解决办法&#xff1a; wa…

Spring 3.1和JPA的持久层

1.概述 本教程显示了如何使用Hibernate作为持久性提供程序使用JPA设置Spring 。 有关使用基于Java的配置和项目的基本Maven pom设置Spring上下文的分步介绍&#xff0c;请参阅本文 。 2. Java的JPA Spring配置 要在Spring项目中使用JPA&#xff0c; 需要设置EntityManager 。…

150928错误认识

1. $arr array(); foreach ($re as $k>$v){  $arr[] $v[updatetime];} $arr的返回结果为&#xff1a; Array ([0] > 2014-09[1] > 2015-04[2] > 2015-09 )$arr array(); foreach ($re as $k>$v){  $arr[$k] $v[updatetime];} $arr的返回结果为&#xff…

STM32F1笔记(一)GPIO输出

GPIO&#xff1a;General Purpose Input Output &#xff08;通用输入/输出&#xff09;。 GPIO最经典应用&#xff1a;LED灯。 先看电路。声明&#xff1a;参考正点原子战舰开发板。 与LED串联的电阻称为限流电阻。 限流电阻计算公式&#xff1a;R(U-LED压降)/20ma。 U为LE…