什么是KVC
设置key value
- (void) setValue:(id) value forKey:(NSString *) key; //类似于set方法
- (id) valueForKey: (NSString *) key; //类似于get方法
- (void) setValue: (id) value forKeyPath: (NSString *) keyPath;
设置undefined key
- (void) setValue: (id) value forUndefinedKey:(NSString *)key;//当key不存在时
设置一组keys
-(void) setValuesForKeysWithDictionary:(NSDictionary *) keyedValues;
-(NSDictionary *) dictionaryWithValuesForKeys: (NSArray *) keys;
根据情况是否触发KVO
+ (BOOL) automaticallyNotifiesObserversForKey:(NSString *)key ;
//缺省是返回yes
下面有一个例子:
例子描述的是关于节目表和节目列表之间的关系:
PlayItem.h
@interface PlayItem :NSObject
{
NSString *_name;
float _price;
}
@property (nonatomic,retain)NSString *name;
@property (nonatomic,assign)float price;
@end
PlayItem.m
#import <Foundation/Foundation.h>
#import "PlayItem.h"
@implementation PlayItem
@synthesize name = _name;
@synthesize price = _price;
- (void)dealloc{
self.name = nil;
[super dealloc];
}
//如果设置里面不存在的key就会调用该方法
- (void) setValue:(id)value forUndefinedKey:(NSString *)key
{
NSLog(@"function %@ is calling.",NSStringFromSelector(_cmd));
}
@end
PlayList.h
#import <Foundation/Foundation.h>
#import "PlayItem.h"
@interface PlayList : NSObject
{
int _number;
NSString *_name;
PlayItem *_currentItem;//当前播放列表
NSMutableArray *_itemList;
}
@property (nonatomic,retain) NSMutableArray *itemList;
@property (nonatomic,assign) int number;
@property (nonatomic,retain) NSString *name;
@property (nonatomic,retain) PlayItem *currentItem;
@end
PlayList.m
#import "PlayList.h"
@implementation PlayList
@synthesize itemList = _itemList,number = _number,name = _name,currentItem = _currentItem;
-(void) dealloc {
self.currentItem = nil;
self.itemList = nil;
self.name = nil;
[super dealloc];
}
- (id)init{
self = [super init];
if (self) {
self.currentItem = [[[PlayItem alloc]init]autorelease];
self.itemList = [NSMutableArray array];
for (int i = 0; i <20; i++) {
PlayItem *pi = [[PlayItem alloc] init];
pi.name = [NSString stringWithFormat:@"name %i",i];
pi.price = 100+i;
[self.itemList addObject:pi];
[pi release];
}
}
return self;
}
//调用setValue:forKey:方法时,参数key不存在时调用此方法
-(void)setValue:(id)value forUndefinedKey:(NSString *)key
{
NSLog(@"file %s function %@ is calling.",__FILE__,NSStringFromSelector(_cmd));
}
@end
main.m
#import "PlayList.h"
#import "PlayItem.h"
int main ()
{
@autoreleasepool {
PlayList *pl = [[PlayList alloc] init];
[pl setValue:@"大连实德" forKey:@"_name"];//forKey可以改为forKeyPath
NSLog(@"pl name:%@",pl.name);
id v = [pl valueForKey:@"number"];
NSLog(@"number: %@",v);
//设置pl.currentItem.name字段
[pl setValue:@"当前播放列表" forKeyPath:@"currentItem.name"];
//forKeyPath不可以改为forKey
NSLog(@"pi.currentItem.name:%@",pl.currentItem.name);
//设置一批key值
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"dalianshide",@"name",@"90",@"number", nil];
[pl setValuesForKeysWithDictionary:dict];
NSLog(@"number is :%i,name is :%@",pl.number,pl.name);
//如果对象中没有key
[pl setValue:@"aishide " forKey:@"test"];
id obj= [pl valueForKey:@"itemList"];
NSLog(@"itemList:%@,%@",pl.itemList,obj);
id obj2 = [pl.itemList valueForKeyPath:@"_name"];
//id obj2 = [pl valueForKeyPath:@"itemList.name"];
NSLog(@"itemList.name:%@",obj2);
NSLog(@"itemList price sum is %@",[pl.itemList valueForKeyPath:@"@sum.price"]);
//@sum.price来对pl.itemList中所有price的进行求和
NSLog(@"itemList price avg is %@",[pl.itemList valueForKeyPath:@"@avg.price"]);
NSLog(@"itemList price max is %@",[pl.itemList valueForKeyPath:@"@max.price"]);
NSLog(@"itemList price min is %@",[pl.itemList valueForKeyPath:@"@min.price"]);
}
return 0;
}