KVC&KVO&NSNotification

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

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

#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@property(nonatomic,strong)Person* p;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.p=[[Person alloc]init];
self.p.father=[[Person alloc]init]; //KVC 演示
[self.p setValue:@"mrzhang" forKey:@"name"];
[self.p setValue:@"laozhang" forKeyPath:@"father.name"]; NSString* name=[self.p valueForKey:@"name"]; NSLog(@"person:name:%@ father name:%@",name,self.p.father.name);
}

使用plist 来加载,直接可以对 对象里的实例进行赋值或读取

Person.h

KVC&KVO&NSNotification

person.plist 文件如下图

KVC&KVO&NSNotification

   NSString* path=[[NSBundle mainBundle] pathForResource:@"person" ofType:@"plist"];

    NSArray * arr=[NSArray arrayWithContentsOfFile:path];

   //可以直接取father 属性 不需要我们先实例出Father对象
NSLog(@">>>%@", [arr valueForKeyPath:@"father.name"]);

K-V 的形式取值或赋值减小了耦合度,key 与 key path 要区分开来,key 可以从一个对象中获取值,而 key path 可以将多个 key 用点号 “.” 分割连接起来

 KVO:

当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者

KVO的优点:
当 有属性改变,KVO会提供自动的消息通知。这样的架构有很多好处。首先,开发人员不需要自己去实现这样的方案:每次属性改变了就发送消息通知。这是KVO 机制提供的最大的优点。因为这个方案已经被明确定义,获得框架级支持,可以方便地采用。开发人员不需要添加任何代码,不需要设计自己的观察者模型,直接可 以在工程里使用。其次,KVO的架构非常的强大,可以很容易的支持多个观察者观察同一个属性,以及相关的值。
KVO如何工作:
需要三个步骤来建立一个属性的观察员。理解这三个步骤就可以知道KVO如何设计工作的。

(1)首先,构思一下如下实现KVO是否有必要。比如,一个对象,当另一个对象的特定属性改变的时候,需要被通知到。
例 如,A对象希望能够觉察到B对象的age属性的任何变化。

(2)那么 A必须发送一个“addObserver:forKeyPath:options:context:”消息,注册成为 B属性的观察者。(说 明:“addObserver:forKeyPath:options:context:”方法在指定对象实例之间建立了一个连接。注意,这个连接不是两 个类之间建立的,而是两个对象实例之间建立的。)

【被监听对象 addObserver 监听者 forKeyPath 被监听对象的属性 options监视内容(新值或旧值)context额外信息】;

(3)为了能够响应消息,观察者必须实现 “observeValueForKeyPath:ofObject:change:context:”方法。这个方法实现如何响应变化的消息。在这个方 法里面我们可以跟自己的情况,去实现应对被观察对象属性变动的相应逻辑。

(4)假如遵循KVO规则的话,当被观察的属性改变的话,方法 “observeValueForKeyPath:ofObject:change:context:”会自动被调用。

需要强调的是KVO的回调要被调用,属性必须是通过KVC的方法来修改的,如果是调用类的其他方法来修改属性,这个观察者是不会得到通知的。

NSNotification:

1、监听通知

【center addObserver :监听者 selector:须执行的方法 name:所监听者通知的名称 object:通知发送者】;

2、通知中心发布消息

【center PostNotificationName:@“test”object:@"11"】;

for example:

- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(test:) name:@"testNotice" object:@"test"]; [[NSNotificationCenter defaultCenter]postNotificationName:@"testNotice" object:@"test"];
} -(void)test:(NSNotification*)noti{
NSLog(@"name:%@,object:%@",noti.name,noti.object); }

总结:KVO与NSNotification

相同点:都可以通过addObserver 方法来监听,都是能通过监听获得处理

不同点:触发点不一样   KVO在属性上通过 K-V 发生改变时,自动调用observeValueForKeyPath方法

而NSNotification 在需要的时候 发送通知才调用,且方法自定义

上一篇:深入理解 KVC\KVO 实现机制 — KVO


下一篇:【转】 KVC/KVO原理详解及编程指南