一、KVC与KVO


*KVC”:key value Coding(键值编码)

*目的:间接修改或获取对象的属性,降低程序(类与类)之间的耦合度.


*KVO”:key value Observer(键值观察),观察者模式.(检测模型变化用的多)

*目的:通常用于观察某个对象的某个属性发生变化时,及时做出相应.


二、KVC的使用方式

KVC被称为iOS开发平台的大招!!! 能快速修改对象属性。

*[p1setValue:@“xxxx”forKeyPath:@“name”];修改指定对象属性.

*[arrvalueForKeyPath:@“book.bookName”];  获取对象属性.

*KVC通过键能直接取得数组.

*在使用KVC时, 一定要保证键值是存在的.

*原理: KVC取值时, 如果发现取值的对象不包含指定的键值,会自动进入对象内部成员进行查找.


三、KVO的使用方式


*KVO通常用于观察对象某个属性发生变化时,做出相应的反应.(多用于观察模型数据)

*KVO和通知中心的一个区别 : KVO只能盯着某个对象(在当前区域内部工作),通知中心可以穿越很多层(如viewController).

*KVO使用步骤:

*1.[stuaddObserver:selfforKeyPath:@"name" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:@"myObserver"];

*2.observeValueForKeyPath.  当指定键值发生改变时, 会自动调用这个方法

*3.removeObserver. 所有观察者模式的性能都不好,需要及时移除。


直接上代码:

[objc] view plain copy 在CODE上查看代码片派生到我的代码片

  1. //  

  2. //  XNViewController.m  

  3. //  KVC----KVO  

  4. //  

  5. //  Created by neng on 14-6-21.  

  6. //  Copyright (c) 2014年 neng. All rights reserved.  

  7. //  

  8.   

  9. #import "XNViewController.h"  

  10. #import "XNPerson.h"  

  11. #import "XNStudent.h"  

  12. #import "XNBook.h"  

  13.   

  14. @interface XNViewController ()  

  15.   

  16. @end  

  17. /** 

  18.  *  KVC: Key Value Coding(键值编码) 

  19.  *  间接修改/获取对象的属性, 降低类与类之间的耦合度. 

  20.  *  KVO: Key Value Observer(键值观察) 

  21.    KVO通常用于观察”对象的某个属性“发生变化时,及时做出响应! 

  22.    而NSNotificationCenter是需要POST"通知字符串"(表示监听的事件类型)的对象存在,通知中心才能够工作! 

  23.  */  

  24.   

  25. @implementation XNViewController  

  26.   

  27. - (void)viewDidLoad {  

  28.     [super viewDidLoad];  

  29.     //1.简单的修改对象属性  

  30.     [self kvcDemo1];  

  31.     //2.对于子类, 也能直接修改  

  32.     [self kvcDemo2];  

  33.     //3.修改对象的book属性. (相当麻烦, 好要创建book对象).KVC一句话  

  34.     [self kvcDemo3];  

  35.     //4.获取对象的属性值. 可批量获取(如果是数组的话).  

  36.     [self kvcDemo4];  

  37.   

  38.     //KVO 演示  

  39.     [self kvoDemo];  

  40. }  

  41.   

  42. - (void)kvoDemo {  

  43.     XNStudent *stu = [[XNStudent alloc] init];  

  44.     stu.name = @"xuneng";  

  45.     //设置监听对象  

  46.     //1》 负责观察的对象 self  

  47.     //2》 观察的键值路径  

  48.     //3》 观察的选项  

  49.     //4》 上下文:通常用于区分不同的观察事件  

  50.     [stu addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"myObserver"];  

  51.   

  52.     stu.name = @"neng"//修改  

  53.   

  54.     //所有观察者模式的性能都不好, 需要及时移除  

  55.     [stu removeObserver:self forKeyPath:@"name"];  

  56.   

  57.     stu.name = @"xu";  //移除后再次修改  

  58. }  

  59.   

  60. /** 

  61.    当KVO指定的对象键值发生改变时, 会自动调用该方法 

  62.    name:      观察的键值 

  63.    object:    观察的对象 

  64.    change:    修改的字典(新旧数值) 

  65.    context:   指定观察者时传入的上下文 

  66.  */  

  67. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(voidvoid *)context {  

  68.     NSLog(@"|-- %@ --|-- %@ --|-- %@ --|-- %@--|", keyPath, object, change, context);  

  69. }  

  70.   

  71. /** 

  72.  *简单的修改对象属性 

  73.  */  

  74. - (void)kvcDemo1 {  

  75.     //1.原始的方式. 点语法修改对象属性的值  

  76.     XNPerson *p1 = [[XNPerson alloc] init];  

  77.     p1.name = @"xuneng";  

  78.     p1.age = 24;  

  79.     //    NSLog(@"%@ , %d",p1.name,p1.age);  

  80.     NSLog(@"KVC1 demo1--> %@", p1); //这样直接调用description方法.  

  81.   

  82.     //2.KVC来修改  

  83.     [p1 setValue:@"xxxx" forKeyPath:@"name"];  

  84.     [p1 setValue:@"10" forKeyPath:@"age"];  

  85.     NSLog(@"KVC2 demo1--> %@ , %d", p1.name, p1.age);  

  86. }  

  87.   

  88. /** 

  89.  *对于子类, 也能直接改 

  90.  */  

  91. - (void)kvcDemo2 {  

  92.     //1.传统方法  

  93.     XNStudent *p1 = [[XNStudent alloc] init]; //学生  

  94.     p1.name = @"student xuneng";  

  95.     p1.age = 22;  

  96.     //    NSLog(@"%@ , %d",p1.name,p1.age);  

  97.     NSLog(@"KVC1 demo2--> %@", p1); //这样直接调用description方法.  

  98.   

  99.     //2.KVC来修改子类  

  100.     [p1 setValue:@"xxxx" forKeyPath:@"name"];  

  101.     [p1 setValue:@"10" forKeyPath:@"age"];  

  102.     NSLog(@"KVC2 demo2--> %@ , %d", p1.name, p1.age);  

  103. }  

  104.   

  105. /** 

  106.  *修改对象的book属性. (相当麻烦, 好要创建book对象).KVC一句话 

  107.  */  

  108. - (void)kvcDemo3 {  

  109.     //1.传统方法  

  110.     XNStudent *p1 = [[XNStudent alloc] init]; //学生  

  111.     p1.name = @"student xuneng";  

  112.     p1.age = 22;  

  113.     XNBook *myBook = [[XNBook alloc] init];  

  114.     myBook.bookName = @"iOS";  

  115.     p1.book = myBook;  

  116.     NSLog(@"KVC1 demo3--> %@", p1);  

  117.   

  118.     //2.KVC的方法  

  119.     [p1 setValue:@"iPhone" forKeyPath:@"book.bookName"]; //学生里的book,book里的bookName  

  120.     NSLog(@"KVC2 demo3--> %@", p1);  

  121. }  

  122.   

  123. /** 

  124.  *获取对象的属性值. 可批量获取(如果是数组的话). 

  125.  */  

  126. - (void)kvcDemo4 {  

  127.     XNStudent *p1 = [[XNStudent alloc] init]; //学生1  

  128.     p1.name = @"student1 xuneng";  

  129.     p1.age = 24;  

  130.     XNBook *myBook1 = [[XNBook alloc] init];  

  131.     myBook1.bookName = @"iOS";  

  132.     p1.book = myBook1;  

  133.   

  134.     XNStudent *p2 = [[XNStudent alloc] init]; //学生2  

  135.     p2.name = @"student2 xuneng";  

  136.     p2.age = 23;  

  137.     XNBook *myBook2 = [[XNBook alloc] init];  

  138.     myBook2.bookName = @"iPhone";  

  139.     p2.book = myBook2;  

  140.   

  141.     NSArray *arr = @[p1, p2];  

  142.   

  143.     //1.普通方法获取数组中对象的属性  

  144.     NSMutableArray *arrBook = [[NSMutableArray alloc] init];  

  145.     for (XNStudent *stu in arr) {  

  146.         [arrBook addObject:stu.book.bookName];  

  147.     }  

  148.     NSLog(@"KVC1 demo4--> %@", arrBook);  

  149.   

  150.     //2.KVC方法来获取数组中对象  

  151.     NSLog(@"KVC2 demo4--> %@", [arr valueForKeyPath:@"book.bookName"]);  

  152. }  

  153.   

  154. @end