ObjC: 使用KVO
KVC很多人都知道,那么什么是KVO呢?Key Value Observing,直譯為:基于鍵值的觀察者。
主要用于有關視圖界面交互編程中,比如,實體(或者叫名詞、或者叫域模型),在應用中表示名詞的部分,類似Java中的Java Bean。再具體點兒,在下文的示例中。圖書(Book類),就是個實體。它的屬性有書名(name)和價格(price)。那么,在界面開發中,可能有多個視圖和這個實體有關聯。如果等實體(Book)的價格(price)發生了變化,這些關聯的界面都要被修改。
比較好的做法是使用觀察者模式,各個界面都注冊觀察者,觀察圖書的價格變化,當變化后改動自己的視圖。
ObjC中提供了這個模式的解決方案,就是KVO。以下用簡單示例說明KVO的實現方式。
Book類,頭文件:
#import <Foundation/Foundation.h>@interface Book : NSObject {
NSString *name;
float price;
}
@end
?
Book類的實現文件,沒做任何事情,不貼了。
?
現在,假設我有個視圖,MyView,我這里為了不帶入實際視圖類的復雜性,只是模擬一個。用普通類。頭文件:
?
#import <Cocoa/Cocoa.h>@class Book;
@interface MyView : NSObject {
Book *book;
}
- (id) init:(Book *)theBook;
@end
實現文件:
?
#import "MyView.h"@implementation MyView
- (id) init:(Book *)theBook {
if(self=[super init]){
book=theBook;
[book addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
}
return self;
}
- (void) dealloc{
[book removeObserver:self forKeyPath:@"price"];
[super dealloc];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context{
if([keyPath isEqual:@"price"]){
NSLog(@">>>>>>>price is changed");
NSLog(@"old price is %@",[change objectForKey:@"old"]);
NSLog(@"new price is %@",[change objectForKey:@"new"]);
}
}
@end
這里的init方法中,可以看到向book實例增加了觀察者,是針對價格price屬性的。這里用的:
?
可以讓通知攜帶舊的price值和新的price值。后面會看到。observeValueForKeyPath方法,就是當price屬性發生變化后,調用的方法。
?
main方法中調用的代碼:
?
Book *book4=[[Book alloc] init];NSArray *bookProperties=[NSArray arrayWithObjects:@"name",@"price",nil];
NSDictionary *bookPropertiesDictionary=[book4 dictionaryWithValuesForKeys:bookProperties];
NSLog(@"book values: %@",bookPropertiesDictionary);
[[[MyView alloc] init:book4] autorelease];
NSDictionary *newBookPropertiesDictionary=[NSDictionary dictionaryWithObjectsAndKeys:@"《Objective C入門》",@"name",
@"20.5",@"price",nil];
[book4 setValuesForKeysWithDictionary:newBookPropertiesDictionary];
NSLog(@"book with new values: %@",[book4 dictionaryWithValuesForKeys:bookProperties]);
?
在這里引發了price屬性變化,觸發了MyView的處理。
?
另外,要注意,在Book實例釋放前,要刪除觀察者,否則會報錯,這里是在MyView里面實現的:
?
- (void) dealloc{[book removeObserver:self forKeyPath:@"price"];
[super dealloc];
}
這里假定MyView實例的生命周期小于等于Book實例。實際使用可能要根據情況在合適的地方addObserver和removeObserver。
?
?
?
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的ObjC: 使用KVO的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL学习笔记_10_MySQL高级
- 下一篇: 矩阵的秩最小化