QF——OC中的KVC,KVO

KVC: (Key Value Coding) 键值编码

  所谓KVC,其实就是不通过set和get方法访问对象属性,而是通过属性名字符串动态的去读取属性。KVC其实也是OC反射机制的一种运用。

  之所以每个对象都有KVC能力,是因为NSObject类实现了NSKeyValueCoding协议。

  属性赋值: setValue:属性值 forKey:属性名

  属性读取:   valueForKey:属性名

   KVC比较常用的用处是在网络请求后要把得到NSDictionary数据要装入Model中,若要通过以往set方法赋值很麻烦,这时可以采用KVC方式,即model对象调用 setValuesForKeysWithDictionary:方法。这样简单粗暴,但是要注意参数dict中的键要和model的属性对应。一般必须要重写

KVO:(Key Value Observer)键值监听

  KVO的实现是因为NSObject类实现了NSKeyValueObserver协议,所以每个类都有KVO能力。

  当我们对对象的某属性敏感时,可以对该属性添加观察者,当该对象的这个属性值发生改变时就会触发回调方法。

  它的本质是观察者模式。(不过添加观察者和回调方法都是自己的方式,有别于观察者模式)

         KVO一般应用在数据模型值发生改变,UI界面随即显示新值。给model某属性添加观察,当值改变时触发回调方法:改变UI的UIlabel的的内容。

  实现KVO的步骤:

    1.给对象的某属性注册观察者(监听者):

    2.重写回调方法(当属性改变时触发)

    3.重写dealloc方法,在里面销毁观察者。

KVO和通知中心的本质都是观察模式,不过KVO是对于任何对象的属性都可以被观察;但通知中心是系统提供的,而且它是单例的。

Person.h

 

#import <Foundation/Foundation.h>

#import "BankCard.h"



@interface Person : NSObject



@property(nonatomic,copy) NSString * name;

@property(nonatomic,retain)BankCard * card;



@end

 

Person.m

#import "Person.h"



@implementation Person



- (void)setCard:(BankCard *)card

{

    _card = card;

    [self.card addObserver:self forKeyPath:@"money" options:NSKeyValueObservingOptionNew context:nil];  //为card属性的money项注册观察者(监听器)

}



//重写observeValueForKeyPath方法。回调方法,若money值发生改变,则触发

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

    if([keyPath isEqualToString:@"money"])

    {

        NSLog(@"您账户的余额发生变动,余额为%i",self.card.money);

    }

}





//重写dealloc方法,移除监听。当

- (void)dealloc

{

    [self.card removeObserver:self forKeyPath:@"money"]; //移除监听

}



@end

BankCard.h

#import <Foundation/Foundation.h>



@interface BankCard : NSObject



@property(nonatomic,assign) long cardID;

@property(nonatomic,assign) int money;



@end

BankCard.m

#import "BankCard.h"



@implementation BankCard







@end

main.m

#import <Foundation/Foundation.h>

#import "Person.h"

#import "BankCard.h"



int main(int argc, const char * argv[])

{



    @autoreleasepool {

        

        Person * person = [[Person alloc]init];

        BankCard * card = [[BankCard alloc]init];

        card.money = 1000;

        person.card = card;

        

        NSLog(@"卡被盗了后...");

        card.money = 0;

        

        

    }

    return 0;

}

 

在Person类中,为card属性的money项注册了监听器,当银行卡被盗了后,人家把余额取完了。因为money的值发生了改变,所以重写的回调方法触发。

 

参考:点击进入 

 

你可能感兴趣的:(VC)