KVC和KVO
Posted JeffreyW
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KVC和KVO相关的知识,希望对你有一定的参考价值。
KVC和KVO
1.KVC: key for Coding,KVC,即是指NSKeyValueCoding,一个非正式的Protocol(协议),提供一种机制来间接访问对象的属性,而KVO是基于KVC的.
KVC需要针对属性来说,比如一个类Student,它有属性name,一般来讲,所谓的key只是个字符串,一般比如Student属性name的key,那么就是@”name”,而它对应的值可以是任意类型的对象比如@”name”这个key对应的值(value)可以是个字符串@”Jim”,也可以是一个类,类名叫Name,里面可能还有更多的属性familyName,secondName.这要看你如何来定义这个value,以下为例子
//先定义一个Dog类的实例变量dog
Student *Jim = [Student alloc] init];
//定义一个Name类
Name *nameForJim = [Name alloc] init];
name.familyName = @"Wang";
//使用KVC给Jim的name属性赋值(即把Jim的"name"这个key赋一个value,这个value为nameForJim,是一个Name类,个人理解为就是Jim.name = nameForJim;初学,有错误请纠正
[Jim setValue:nameForJim forKey:@"name"];
//获取Jim的name,个人理解为使用一个Name实例来获取Jim的name属性
Name *nameForJim = [Jim valueForKey:@"name"];
如果需要在更下一层的使用,则需要使用valueForKeyPath,比如这里需要获取到Jim的familyName的值@"Wang",实现后相当于是NSString *familyNameForJim =Jim.name.familyName:
NSString *familyNameForJim = [Jim valueForKeyPath:@"name.familyName"];
也相当于:
[[Jim valueForKey:@"name"] valuForKey:@"familyName"];
2.KVO:Key -Value Observing,它是建立在KVC的基础之上,能观察到对象的KVC的变化
如上都设置好以后,如果Jim突然有一天改名字了,改叫Tom,这个时候,我们需要做一件事情,那就是把这个消息告诉他的女朋友Lucy,但是可能Lucy可能在很远的地方,这时候我们就可以使用KVO,个人感觉有的点类似通知:
//先定义下这个Tom的名字nameForTom,这是一个全新的名字,内部我们不管他是姓王还是姓朴,我们要达到的目的是,只要Jim改成这个名字了,就告诉Lucy(Lucy这个名字没有意义,只是说这件事情而已,不要纠结她的构成了...)
Name *nameForTom = [Name alloc] init];
[Jim setValue:nameForTom forKey:@"name"];
//好了,名字改好了,我们该添加观察者了,下面的options是观察的地方的单数设置,可以取new或者old,到时候可以调用字典
[Jim addObserver:observer
forKeyPath:@"age"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:[Jim class]];
//以下代码从别处转载大致改了下,但是这个context还是不太理解,若有看到此处的,请给点指点:
- (void) observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
if ([keyPath isEqualToString:@"age"])
Class classInfo = (Class)context;
NSString * className = [NSString stringWithCString:object_getClassName(classInfo)
encoding:NSUTF8StringEncoding];
NSLog(@" >> class: %@, name changed", className);
NSLog(@" old name is %@", [change objectForKey:@"old"]);
NSLog(@" new name is %@", [change objectForKey:@"new"]);
//然后执行 告诉Lucy他改名字了这样一个方法
[self tellLucyThatJimHasChangedAName];
else
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
个人理解是这样子:keyPath即观察的类的keyPath,比如现在咱们要观察的Jim,他要变动的就是@"name",如果你要观察多个都有这个属性的类,那么需要判断是谁(参数object)的这个@"name".context看着像是类型,这里没有太理解,然后change参数对应传过来的是比如old即改变之前的值,和new改变之后的值,需要用到哪些值,在之前加入观察者的时候的option模式中设置,一般设置为new和old.
以上是关于KVC和KVO的主要内容,如果未能解决你的问题,请参考以下文章