iOS:KVO/KVC 的概述与使用

  • Post author:
  • Post category:其他




KVO






APP开发技术QQ群:347072638


一,概述



KVO,



即:



Key-Value Observing



,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。




二,使用方法


系统框架已经支持KVO,所以程序员在使用的时候非常简单。


1. 注册,指定被观察者的属性,


2. 实现回调方法


3. 移除观察




三,实例:


假设一个场景,股票的价格显示在当前屏幕上,当股票价格更改的时候,实时显示更新其价格。


1.定义DataModel,


  1. @interface StockData : NSObject {
  2. NSString * stockName;

  3. float

    price;
  4. }
  5. @end
  6. @implementation StockData
  7. @end



2.定义此model为Controller的属性,实例化它,监听它的属性,并显示在当前的View里边

  1. – (

    void

    )viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. stockForKVO = [[StockData alloc] init];
  5. [stockForKVO setValue:@

    “searph”

    forKey:@

    “stockName”

    ];
  6. [stockForKVO setValue:@

    “10.0”

    forKey:@

    “price”

    ];
  7. [stockForKVO addObserver:self forKeyPath:@

    “price”

    options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
  8. myLabel = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 30 )];
  9. myLabel.textColor = [UIColor redColor];
  10. myLabel.text = [stockForKVO valueForKey:@

    “price”

    ];
  11. [self.view addSubview:myLabel];
  12. UIButton * b = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  13. b.frame = CGRectMake(0, 0, 100, 30);
  14. [b addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
  15. [self.view addSubview:b];
  16. }








3.当点击button的时候,调用buttonAction方法,修改对象的属性


  1. -(

    void

    ) buttonAction
  2. {
  3. [stockForKVO setValue:@

    “20.0”

    forKey:@

    “price”

    ];
  4. }



4. 实现回调方法

  1. -(

    void

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

    void

    *)context
  2. {

  3. if

    ([keyPath isEqualToString:@

    “price”

    ])
  4. {
  5. myLabel.text = [stockForKVO valueForKey:@

    “price”

    ];
  6. }
  7. }



5.增加观察与取消观察是成对出现的,所以需要在最后的时候,移除观察者

  1. – (

    void

    )dealloc
  2. {
  3. [super dealloc];
  4. [stockForKVO removeObserver:self forKeyPath:@

    “price”

    ];
  5. [stockForKVO release];
  6. }





四,小结






KVO这种编码方式使用起来很简单,很适用与datamodel修改后,引发的UIVIew的变化这种情况,就像上边的例子那样,当更改属性的值后,监听对象会立即得到通知。



KVC



一,概述





KVC


是KeyValueCoding

的简称,它是一种可以直接通过字符串的名字(key)来访问类属性的机制。而不是通过调用Setter、Getter方法访问。


当使用KVO

、Core Data、CocoaBindings、AppleScript(Mac支持)时,KVC是关键技术。





二,使用方法



关键方法定义在:NSKeyValueCodingprotocol


KVC


支持类对象和内建基本数据类型。




获取值


valueForKey:


,传入NSString


属性的名字。


valueForKeyPath:


,传入NSString


属性的路径,xx.xx形式。


valueForUndefinedKey


它的默认实现是抛出异常,可以重写这个函数做错误处理。





修改值


setValue:forKey:


setValue:forKeyPath:


setValue:forUndefinedKey:


setNilValueForKey:



当对非类对象属性设置nil

时,调用,默认抛出异常。




一对多关系成员的情况


mutableArrayValueForKey


:有序一对多关系成员

NSArray


mutableSetValueForKey


:无序一对多关系成员

NSSet





三,实例:



1.






1

.Person









2.






@implementation

Person




3.






@synthesize

name,age;


//


属性


name



将被监视






4.






-(void)

changeName




5.






{




6.










name=@”changeName

directly”;




7.






}




8.






@end




9.










10.







11.



2.PersonMonitor









监视了


name


属性






12.



@implementation

PersonMonitor




13.







14.





(void)observeValueForKeyPath:(NSString

*)keyPath




15.

























ofObject:(id)object




16.



























change:(NSDictionary

*)change




17.


























context:(void

*)context




18.



{




19.







if

([keyPath

isEqual:@”name”])




20.







{




21.











NSLog(@”change

happen,

old:%@



new:%@”,[change

objectForKey:NSKeyValueChangeOldKey],[change

objectForKey:NSKeyValueChangeNewKey]);




22.







}




23.



}




24.



@end




25.







26.







27.



3


测试代码






28.







29.








//


初始化被监视对象






30.







Person

*p

=[[Person

alloc]

init];




31.








//


监视对象






32.






PersonMonitor

*pm=

[[PersonMonitor

alloc]init];




33.







[p

addObserver:pm

forKeyPath:@”name”

options:(NSKeyValueObservingOptio

nNew

|NSKeyValueObservingOptio

nOld)

context:nil];




34.









35.



//


测试前的数据






36.







NSLog(@”p.name

is

%@”,p.name);




37.










38.



//


通过


setvalue



的方法,


PersonMonitor


的监视将被调用






39.





[p

setValue:@”name

kvc”

forKey:@”name”];




40.








41.



//


查看设置后的值






42.






NSLog(@”p

name

get

by

kvc

is

%@”,[p

valueForKey:@”name”]);




43.







44.



//


效果和通过


setValue



是一致的












45.



p.name=@”name

change

by

.name=”;




46.







47.






//


通过


person


自己的函数来更改


name







48.








[p

changeName];





49.







50.






结果是






51.



输出






52.



2011-07-03



16:35:57.406

Cocoa[13970:903]

p.name

is

name




53.



2011-07-03



16:35:57.418

Cocoa[13970:903]

change

happen,

old:name



new:name

kvc




54.



2011-07-03



16:35:57.420

Cocoa[13970:903]

p

name

get

by

kvc

is

name

kvc




55.



2011-07-03



16:35:57.421

Cocoa[13970:903]

change

happen,

old:name

kvc



new:name

change

by

.name=




56.





最后一次修改是直接修改






所以没法产生通知









四,小结






KVO/

KVC

这种编码方式使用起来很简单,很适用与datamodel修改后,引发的UIVIew的变化这种情况,就像上边的例子那样,当更改属性的值后,监听对象会立即得到通知。





版权声明:本文为messageloop3原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。