iOS开发 - KVC

KVC原理与实践
本文详细介绍了Objective-C中键值编码(KVC)的基本概念、常用方法及其底层实现原理,并通过实例演示了如何使用KVC来操作对象属性。

1、简介

1> KVCKey Value Coding,键值编码

2> 允许以字符串的形式间接的操作对象的属性

3> 其他操作属性的方式:set方法、get方法、点语法

2、常用方法

setValue:属性值 forKey:属性名      为指定属性设置值

valueForKey:属性名      获取指定属性的值

关键代码

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *number;
@property (nonatomic, copy) NSDate *birthday;

// 使用KVC的方式为属性赋值
// 强调:属性值可以是任何类型的对象
[man setValue:@"华安" forKey:@"name"];
[man setValue:@"9527" forKey:@"number"];
[man setValue:[[NSDate alloc]init] forKey:@"birthday"];

3、KVC底层

1、setValue:属性值 forKey:@"name"

1> 调用setName:方法,通过set方法完成设置

2> 对_name成员变量赋值,与其定义的位置和修饰符无关,都是对_name赋值

3> 对name成员变量赋值,与其定义的位置和修饰符无关,都是对name赋值

4> 执行该对象的setValue: forUndefinedKey:方法

2、valueForKey:@"name"

1> 调用name方法,通过get方法获取返回值

2> 返回_name成员变量的值,与其定义的位置和修饰符无关,都是返回_name的值

3> 返回name成员变量的值,与其定义的位置和修饰符无关,都是返回name的值

4> 执行该对象的valueforUndefinedKey:方法

4、处理不存在的key

[p setValue:@"Stephen" forKey:@"name"];

// *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<Person 0x10010e2f0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key name.'

// 原因:没有name这个key

// 解决:重写 setValue: forUndefinedKey:这个方法

5、处理nil值

// 使用KVC的方式为属性赋值
// 强调:KVC中,int类型的属性不能接受nil值
[goods setValue:nil forKey:@"name"];
[goods setValue:nil forKeyPath:@"price"];

// int类型的属性值为nil时(基本类型的属性值为nil时都会如此)

// 出现的错误
// *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '[<Product 0x10010e2e0> setNilValueForKey]: could not set nil as the value for the key price.'

// 错误的原因
// 不能把price这个key的值设置为nil,而这里设置成了nil

// 分析该错误
// 该错误实际上是由setNilValueForKey:方法产生的,即如果设置某个属性值为nil,但是该属性却不接受nil值时,程序自动执行该对象的setNilValueForKey:方法

// 解决该错误
// 重写该对象的 setNilValueForKey: 方法

// 使用KVC的方式为属性赋值
// 强调:KVC中,int类型的属性不能接受nil值
[goods setValue:nil forKey:@"name"];
[goods setValue:nil forKeyPath:@"price"];

// int类型的属性值为nil时(基本类型的属性值为nil时都会如此)

// 出现的错误
// *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '[<Product 0x10010e2e0> setNilValueForKey]: could not set nil as the value for the key price.'

// 错误的原因
// 不能把price这个key的值设置为nil,而这里设置成了nil

// 分析该错误
// 该错误实际上是由setNilValueForKey:方法产生的,即如果设置某个属性值为nil,但是该属性却不接受nil值时,程序自动执行该对象的setNilValueForKey:方法

// 解决该错误
// 重写该对象的 setNilValueForKey: 方法
- (void)setNilValueForKey:(NSString *)key
{
    if ([key isEqualToString:@"price"]) { // price属性
        price = 0; // 说明:如果没有@synthesize price;这段代码,则此处使用price = 0;
    } else { 
        [super setNilValueForKey:key]; // 回调父类的setNilValueForKey:方法,即执行默认行为
    }
}

6、KVC的复合属性keyPath

1> 复合属性的概念

假设类型AB

1.如果A对象包含B类型的属性b,而B对象又包含b1b2属性

2.那么b.b1b.b2可称为复合属性

2> 常用方法

setValue:属性值 forKeyPath:属性名        设置复合属性的属性值

valueForKeyPath:属性名      获取复合属性的属性值

3> 关键代码

//  Shopping.h

// 商品
@property (strong, nonatomic) Computer *computer;
// 数量
@property (assign, nonatomic) int amount;

//  Shopping.m

- (int)totalPrice
{
    return computer.price * amount;
}

//  Computer.h

@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) int price;


//  main.m
        
// 创建对象
Shopping *shop = [[Shopping alloc]init];

// KVC赋值
[shop setValue:@"12" forKey:@"amount"];
[shop setValue:[[Computer alloc]init] forKey:@"computer"];

// key路径设置复合属性的值
[shop setValue:@"Mac Pro" forKeyPath:@"computer.name"];

// key路径获取符合属性的值
[shop setValue:[NSNumber numberWithInt:20] forKeyPath:@"computer.price"];

NSLog(@"\n清单为:%@个%@\n总价为:%@",
      [shop valueForKey:@"amount"],
      [shop valueForKeyPath:@"computer.name"],
      [shop valueForKey:@"totalPrice"]
      );
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值