Key Value Coding是cocoa的一個標准組成部分,它能讓我們可以通過name(key)的方式訪問屬性,某些情況下極大地簡化了代碼,可稱之為cocoa的大招。
如下的例子:
- (id)tableView:(NSTableView *)tableview objectValueForTableColumn:(id)column row:(NSInteger)row { ChildObject *child = [childrenArray objectAtIndex:row]; if ([[column identifier] isEqualToString:@name]) { return [child name]; } if ([[column identifier] isEqualToString:@age]) { return [child age]; } if ([[column identifier] isEqualToString:@favoriteColor]) { return [child favoriteColor]; } // And so on. }
- (id)tableView:(NSTableView *)tableview objectValueForTableColumn:(id)column row:(NSInteger)row { ChildObject *child = [childrenArray objectAtIndex:row]; return [child valueForKey:[column identifier]]; }
顯而易見,簡化了很多代碼。
1 給當前對象屬性賦值
- (void)setValue:(id)value forKey:(NSString *)key;
2給對象的屬性的屬性賦值
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
3 處理未定義的鍵
- (void) setValue:(id)value forUndefinedKey:(NSString *)key
4 字典轉模型:會為我們把和dictionary的key名字相同的class proerty設置上dict中key對應的value
- (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;
注意:要求字典中的key和對象屬性一樣,都是基本的OC數據類型:Array/Dictionary/Boolean/Data/Number/String
1 獲取對象屬性的值
- (id)valueForKey:(NSString *)key;
2 獲取對象屬性的屬性的值
- (id)valueForKeyPath:(NSString *)keyPath;
Person * p = [[Person alloc]init]; Car *car = [[Car alloc]init]; p.car = car; [p setValue:@qhyuan forKeyPath:@name]; [p setValue:@(20) forKey:@id]; [p setValue:@baoshijie forKeyPath:@car.brand]; [p setValue:@180000 forKeyPath:@car.price]; NSLog(@kvc賦值的person對象----%@,p); NSString * name = [p valueForKey:@name]; NSString * brand = [p valueForKeyPath:@car.brand]; NSLog(@%@ %@,name, brand);
模型
Person.h
@interface Person : NSObject @property (nonatomic, copy) NSString * name; @property (nonatomic, assign) int age; - (instancetype) initWithDict:(NSDictionary *) dict; + (instancetype) personWithDict:(NSDictionary *) dict; + (NSArray *) person; @endPerson.m
@implementation Person - (instancetype) initWithDict:(NSDictionary *) dict { if(self = [self init]) { // 使用KVC 字典轉模型 如此方便,省去了大量的賦值代碼 [self setValuesForKeysWithDictionary:dict]; //self.name = dict[@name]; //self.age = [dict[@age] integerValue]; } return self; } + (instancetype) personWithDict:(NSDictionary *) dict { return [[self alloc]initWithDict:dict]; } + (NSArray *) person { NSMutableArray * mutablePersons = [NSMutableArray array]; NSString * path = [[NSBundle mainBundle] pathForResource:@persons.plist ofType:nil]; NSArray *persons = [[NSArray alloc] initWithContentsOfFile:path]; for (NSDictionary * person in persons) { [mutablePersons addObject:[self personWithDict:person]]; } return mutablePersons; } - (NSString *) description { NSString * desc = [NSString stringWithFormat:@<%p:(%@,%d)>,self,self.name,self.age]; return desc; } @end
如果將鍵age換成了id
會拋出異常:*** Terminating app due to uncaught exception 'NSUnknownKeyException',reason: '[
重寫以下方法即可,處理未定義的鍵
- (void)setValue:(id)value forUndefinedKey:(NSString *)key;
- (void) setValue:(id)value forUndefinedKey:(NSString *)key { if([key isEqualToString:@id]) key = @age; [super setValue:value forKey:key]; }
Person類增加了一個Car類型的屬性
@property (nonatomic, strong) Car * car;
我們只需要重寫以下方法
- (void)setValue:(id)value forKey:(NSString *)key;
- (void)setValue:(id)value forKey:(NSString *)key { if([key isEqualToString:@cars]) { Car *car = [Car carWithDict:(NSDictionary *)value]; self.car = car; } else [super setValue:value forKey:key]; }打印結果
字典轉模型[5525:60b] (
)