|KVC的用法

1、KVC既键值编码(Key Value Coding),基于NSKeyValueCoding协议,它是以字符串的形式来操作对象的成员变量,也就是通过字符串key来指定要操作的成员变量。基本操作如:

  • setValue:forKey:为成员变量赋值。如:[student setValue:@"大明" forKey:@"name"];
  • valueForKey:获取指定的成员变量。如:NSString *name = [student valueForKey:@"name"];

2、用KVC操作成员变量的底层实现,就拿成员变量name来说吧,一般按如下顺序执行:

  • 程序先尝试调用name的setter或getter方法,就是先调用setName或name方法来设置或获取成员变量。
  • 如果该类没有提供setter或者getter方法,则KVC机制将会搜索该类中名为_name的成员变量。这时无论该成员变量定义在接口部分还是实现部分,KVC的代码底层都会对_name进行赋值或者获取操作。
  • 如果该类既没有setter或者getter方法,也没有_name成员变量,则KVC机制将会搜索该类中名为name的成员变量。这时无论该成员变量定义在接口部分还是实现部分,KVC的代码底层都会对name进行赋值或者获取操作。
  • 如果以上3步都没能找到指定的成员变量,则程序将会执行setValue:forUndefinedKey:或者valueForUndefinedKey:方法抛出异常,默认是终止程序。

3、对于不存在的key怎么处理呢?默认情况下会抛出NSUnknownKeyException异常,并终止程序。

此时可以直接在类的实现部分重写setValue:forUndefinedKey:和valueForUndefinedKey:方法,当KVC找不到指定的成员变量时,会调用这两个方法,通过重写这两个方法可以方便的定制自己的处理方案。

4、setNilValueForKey:方法的调用。

当用KVC的方式把基本数据类型(如int、float等)设置为nil时,会调用成员变量所属类的setNilValueForKey:方法,抛出NSInvalidArgumentException异常,并终止程序。

此时在该类的实现中重写setNilValueForKey:做相应的处理即可。

5、KVC操作对象的复合属性。

复合属性:一个类的属性是另一个类的对象,这个对象的属性就是就是复合属性,比如Person类有个Student类型的属性student,Student类有个name属性,name相对于Person类就是个复合属性。这个复合属性在KVC机制中被称为key路径,即student.name。

在KVC机制中操作key路径的方法如下:

  • setValue:forKeyPath:根据key路径设置属性值。
  • valueForKeyPath:根据key路径获取属性值。

通过KVC操作对象的性能比通过setter和getter方法要差,但是通过KVC比较灵活。

|KVO的用法

KVO即键值监听(Key Value Observe),基于NSKeyValueObserving协议,用于监听属性值的改变(通常是数据模型)。

KVO的用法分三步:

  1. 为对象指定的key路径注册监听器 -> addObserver:forKeyPath:options:context:。
  2. 重写监听方法以得到最新修改的数据 -> observeValueForKeyPath:ofObject:change:context:。
  3. 删除指定key路径的监听器 -> removeObserver:forKeyPah:或者removeObserver:forKeyPath:context。

参数说明:

observer: 观察对象。

forKeyPath:对象的复合属性。

options分别是:

  • NSKeyValueObservingOptionNew:把更改之前的值提供给处理方法
  • NSKeyValueObservingOptionOld:把更改之后的值提供给处理方法
  • NSKeyValueObservingOptionInitial:把初始化的值提供给处理方法,一旦注册,立马就会调用一次。通常它会带有新值,而不会带有旧值。
  • NSKeyValueObservingOptionPrior:分2次调用,在值改变之前和值改变之后。
  • 0:就代表不带任何参数进去。

context: 可以带入一些参数,其实这个挺好用的,任何类型都可以,自己强转就好了。

change:  字典里的key对应options里的NSKeyValueObservingOptionNew、NSKeyValueObservingOptionOld等。

  •  #import "ViewController.h"
    #import "Person.h"
    #import "Student.h" @interface ViewController ()
    @property (strong, nonatomic) Person *person;
    @property (strong, nonatomic) Student *stu;
    @end @implementation ViewController
    - (void)viewDidLoad {
    [super viewDidLoad];
    Person *person = [[Person alloc] init];
    self.person = person;
    Student *stu = [[Student alloc] init];
    self.stu = stu;
    person.height = 1.5;
    person.student = stu;
    stu.height = 1.0;
    stu.age = ;
    [person addObserver:self forKeyPath:@"height" options:NSKeyValueObservingOptionNew context:nil];
    [person addObserver:self forKeyPath:@"student.height" options:NSKeyValueObservingOptionNew context:nil];
    [stu addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil];
    for (int i = ; i < ; i++) {
    [person setValue:@(person.height + i) forKey:@"height"];
    [person setValue:@(person.student.height + i) forKeyPath:@"student.height"];
    [stu setValue:@(stu.age + i) forKey:@"age"];
    } NSLog(@":person.height = %@, stu.height = %@, stu.age = %@", [person valueForKey:@"height"], [person valueForKeyPath:@"student.height"], [stu valueForKey:@"age"]);
    } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    NSLog(@"\n--------------------\n被修改的KeyPath:%@\n被修改的对象:%@\n被修改后的值:%@\n被修改的上下文:%@\n\n\n", keyPath, object, change[NSKeyValueChangeNewKey], context);
    } - (void)dealloc {
    [self.person removeObserver:self forKeyPath:@"height"];
    [self.person removeObserver:self forKeyPath:@"student.height"];
    [self.stu removeObserver:self forKeyPath:@"age"];
    } @end

KVC与KVO的实现原理的更多相关文章

  1. KVC和KVO的理解(底层实现原理)

    1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属性.而不是通过调用Setter.Getter方法访问.KVO 就是基于 KVC 实现的 ...

  2. KVC 和 KVO 简单总结

    KVC: key value coding,键值编码.是一种通过使用属性的名称(key)来间接访问对象属性的方法.这个方法可以不用通过 setter/getter 方法来访问对象的属性.该方法使用的实 ...

  3. iOS中关于KVC与KVO知识点

    iOS中关于KVC与KVO知识点 iOS中关于KVC与KVO知识点  一.简介 KVC/KVO是观察者模式的一种实现,在Cocoa中是以被万物之源NSObject类实现的NSKeyValueCodin ...

  4. 聊聊 KVC 和 KVO 的高阶应用

    KVC, KVO 作为一种魔法贯穿日常Cocoa开发,笔者原先是准备写一篇对其的全面总结,可网络上对其的表面介绍已经够多了,除去基本层面的使用,笔者跟大家谈下平常在网络上没有提及的KVC, KVO进阶 ...

  5. KVC和KVO

    OC中的一个比较有特色的知识点:KVC和KVO 一.KVC操作OC中的KVC操作就和Java中使用反射机制去访问类的private权限的变量,很暴力的,这样做就会破坏类的封装性,本来类中的的priva ...

  6. iOS开发中KVC、KVO简介

    在iOS开发中,KVC和KVO是经常被用到的.可以使用KVC对对象的属性赋值和取得对象的属性值,可以使用KVO监听对象属性值的变化.简单介绍一下KVC和KVO. 一:键值编码(KVC) KVC,全称 ...

  7. iOS KVC 和 KVO 区别简单总结

    KVC: key value coding,键值编码.是一种通过使用属性的名称(key)来间接访问对象属性的方法.这个方法可以不用通过 setter/getter 方法来访问对象的属性.该方法使用的实 ...

  8. KVC、KVO实现过程

    1.KVC的实现过程 以 [object setValue:@"134567" forKey:@"uid"];为例子,来探究KVC的实现过程 第一步:搜索1.首 ...

  9. iOS KVC 和 KVO 的学习

    KVC  (NSKey Value Coding) :键值编码 KVO (Key Value Observing) :键值监听 前言:我曾经用过 监听 一个音频何时结束 监听视频播放 状态等 用了这种 ...

随机推荐

  1. 前端自动化开发之grunt

    上篇文章介绍了前端模块化开发工具seaJs,利用seaJs我们可以轻松实现前端的模块化编程,参见http://www.cnblogs.com/luozhihao/p/4818782.html 那么今天 ...

  2. The Web server is configured to not list the contents of this directory.

    部署一个ASP.NET MVC网站至一个全新的服务器Windows Server 2008 R2, 数据为MS SQL Server 2014 64bit Expression版本. 运行时,它第一次 ...

  3. Ajax实现定时刷新页面

    function deleteValue(){ var refresh = function() { $.ajax({   type:'post',   url:'/Application/index ...

  4. jquery层级原则器(匹配后代元素div)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. TabHost的使用

    Android中的选项卡是用TabHost实现的. 首先,定义TabHost的布局文件: <?xml version="1.0" encoding="utf-8&q ...

  6. 更改(修改)mysql自动增序列改变从1000开始

    更改(修改)mysql自动增序列改变从1000开始 ************************************************************************** ...

  7. Raising Error Conditions with MySQL SIGNAL / RESIGNAL Statements

    http://www.mysqltutorial.org/mysql-signal-resignal/ Summary: in this tutorial, you will learn how to ...

  8. 制作rpm包步骤

    由于项目需要,需要自行制作rpm包.比较全面的可以参考如下链接: http://blog.chinaunix.net/uid-23069658-id-3944462.html 大致框架如下: 1,安装 ...

  9. 将AJAX返回值纵向排序赋值给Table标签

    /*下面是所有拼接这个表的代码*/ 1 function HandelAjaxReturnDataForContentTable(data) { var shareHtml = "" ...

  10. Java--关于计算表达式中赋值的细节问题

    public class Test { public static void main(String[] args) { int t = 0; int p = 0; int q = 0; int ta ...