ios学习8_KVC和字典转模型

来源:互联网 发布:c语言中char数据类型为 编辑:程序博客网 时间:2024/06/06 05:45

Key Value Coding是cocoa的一个标准组成部分,它能让我们可以通过name(key)的方式访问属性,某些情况下极大地简化了代码,可称之为cocoa的大招。

如下的例子:

使用KVC的好处

不使用KVC

- (id)tableView:(NSTableView *)tableviewobjectValueForTableColumn:(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. }

使用KVC

- (id)tableView:(NSTableView *)tableviewobjectValueForTableColumn:(id)column row:(NSInteger)row {    ChildObject *child = [childrenArray objectAtIndex:row];    return [child valueForKey:[column identifier]];}

显而易见,简化了很多代码。

KVC操作

KVC赋值

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

KVC取值

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;@end
Person.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

字典中多个某些key是OC中的关键字


如果将键age换成了id

会抛出异常:

*** Terminating app due to uncaught exception 'NSUnknownKeyException',reason: '[<Person 0x8c419a0> setValue:forUndefinedKey:]: this class isnot key value coding-compliant for the key id.

重写以下方法即可,处理未定义的键

- (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] (

    "<Person:(zhangsan,20,<Car:(benchi,180000)>)>",

   "<Person:(lisi,22,<Car:(baoma,180000)>)>",

   "<Person:(wangwu,24,<Car:(aodi,180000)>)>"

)

如果不只是增加了Cars属性而是增加了Cars数组,也是类似的方式。

3 0
原创粉丝点击