ios学习8_KVC和字典转模型

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

如下的例子:

使用KVC的好处

不使用KVC

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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

}

使用KVC

 

?

1

2

3

4

5

- (id)tableView:(NSTableView *)tableview

objectValueForTableColumn:(id)column row:(NSInteger)row {

    ChildObject *child = [childrenArray objectAtIndex:row];

    return [child valueForKey:[column identifier]];

}

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

KVC操作

KVC赋值

 

1 给当前对象属性赋值

 

?

1

- (void)setValue:(id)value forKey:(NSString *)key;

 

2给对象的属性的属性赋值

 

?

1

- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;

 

3 处理未定义的键

 

?

1

- (void) setValue:(id)value forUndefinedKey:(NSString *)key

 

4 字典转模型:会为我们把和dictionary的key名字相同的class proerty设置上dict中key对应的value

 

?

1

- (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;

 

注意:要求字典中的key和对象属性一样,都是基本的OC数据类型:Array/Dictionary/Boolean/Data/Number/String

 

KVC取值

1 获取对象属性的值

 

?

1

- (id)valueForKey:(NSString *)key;

 

2 获取对象属性的属性的值

 

?

1

- (id)valueForKeyPath:(NSString *)keyPath;


例子:

 

 

?

1

2

3

4

5

6

7

8

9

10

11

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

 

 

?

1

2

3

4

5

6

7

@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

 

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

@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: '[setValue:forUndefinedKey:]: this class isnot key value coding-compliant for the key id.

 

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

 

?

1

- (void)setValue:(id)value forUndefinedKey:(NSString *)key;


解决方式:

 

 

?

1

2

3

4

5

6

- (void) setValue:(id)value forUndefinedKey:(NSString *)key

{

    if([key isEqualToString:@id])

        key = @age;

    [super setValue:value forKey:key];

}

 

字典里面还包含某些对应自定义类的字典或者数组

 

 

Person类增加了一个Car类型的属性

?

1

@property (nonatomic, strong) Car * car;

我们只需要重写以下方法

 

?

1

- (void)setValue:(id)value forKey:(NSString *)key;


解决方法:

 

 

?

1

2

3

4

5

6

7

8

9

10

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

)

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值