KVC和KVO

来源:互联网 发布:人工智能出现表明 编辑:程序博客网 时间:2024/06/03 20:33

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.
0 0
原创粉丝点击