KVC/KVO是觀察者模式的一種實現 KVC全稱是Key-value coding,翻譯成鍵值編碼。顧名思義,在某種程度上跟map的關係匪淺。它提供了一種使用字符串而不是訪問器方法去訪問一個對象實例變量的機制。KVO全稱是Key-value observing,翻譯成鍵值觀察。提供了一種當其它對象屬性被修改的時候能通知當前對象的機制。再MVC大行其道的Cocoa中,KVO機制很適合實現model和controller類之間的通信。編碼
首先咱們建立一個Egg類,給它賦值一個屬性atom
@interface Egg : NSObjectspa
@property (nonatomic ,copy)NSString *weight;翻譯
@endserver
@implementation Egg對象
@endblog
而後咱們在建立一個JianBingGuoZi類 (名字隨便起的),給它設置幾個屬性,其中一個是剛纔咱們定義的Eggip
#import "Egg.h"rem
@interface JianBingGuoZi : NSObject字符串
@property (nonatomic, strong)Egg *egg;
@property (nonatomic, copy)NSString *name;
@property (nonatomic, assign) int price;
@property (nonatomic, copy)NSString *decr;
@end
@implementation JianBingGuoZi
@end
在程序啓動的跟視圖
- (void)viewDidLoad {
[super viewDidLoad];
_egg = [[Egg alloc] init];
_egg.weight = @"80克";
_jian = [[JianBingGuoZi alloc] init];
_jian.name = @"水果餡的煎餅";
_jian.price = 5;
_jian.egg = _egg;
// 1. 使用KVC獲取數據
[self useKVCGetData];
// 2. 使用KVC批處理數據
[self usePiChuLi];
// 3. 鏈性訪問
[self useKeyPath];
// 4. KVO的使用
[self useKVO];
}
- (void)useKVO
{
// 給一個對象添加監聽
// 1. 誰去監聽
// 2. 監聽那個屬性
// 3. 監聽到對象屬性改變的時候傳遞數據是什麼數據
[_jian addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}
// 監聽的對象 若是屬性發生變化就會調用這個方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"%@---%@",change[@"new"],change[@"old"]);
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[_jian setValue:@"狗肉餡的煎餅" forKeyPath:@"name"];
[_jian setValue:@"這是一個煎餅,不是餃子" forUndefinedKey:@"description"];
}
- (void)useKeyPath
{
// 設置屬性值
[_jian setValue:@"200克" forKeyPath:@"egg.weight"];
// 獲取屬性值
[_jian valueForKeyPath:@"egg.weight"];
}
- (void)usePiChuLi
{
// 1. 同時獲取對象的多個屬性
NSArray *array = [NSArray arrayWithObjects:@"name",@"price", nil];
NSDictionary *dict = [_jian dictionaryWithValuesForKeys:array];
// 2. 同時給對象的多個屬性賦值
NSDictionary *dictT = @{
@"name":@"老鼠肉餡的煎餅",
@"price":[NSNumber numberWithInt:15]
};
[_jian setValuesForKeysWithDictionary:dictT];
}
- (void)useKVCGetData
{
// 1.valueForKey 首先查找以name或者isName命名的getter方法,若是沒有這個方法,去對象內部查找名字爲name或者_name命名的實例變量
NSString *name = [_jian valueForKey:@"name"];
// 2. KVC 自動包裝功能,自動將基本數據類型包裝成NSNumber 或者 NSValue 對象
[_jian valueForKey:@"price"];
// 設置屬性值 首先查找以setName命名的setter方法,若是沒有這個方法,去對象內部查找名字爲name或者_name命名的實例變量
[_jian setValue:@"豬肉餡的煎餅" forKey:@"name"];
}
- (void)dealloc
{
// 移除監聽
[_jian removeObserver:self forKeyPath:@"name"];
}
@end
有時候後臺給咱們傳過來的參數包含有關鍵字,咱們在賦值的時候會出錯,好比
可是咱們又不能讓後臺去改返回的數據,這時候咱們就能夠這麼寫,把屬性名字更改
而後再重寫這個方法就好了