1. 基本概念
KVC,即是指 Key-Value-Coding,一个非正式的 Protocol,提供一种机制来间接访问对象的属性。
为了说明其使用场合,首先建立一个Person类,然后分以下几点进行说明。
@class Card; @interface Person : NSObject @property (nonatomic,copy)NSString *name; @property (nonatomic,assign) int age; /* 引用了其他一个对象 */ @property (nonatomic,strong) Card *card; @end
2. 使用场合
Situation One: 方法的形式参数是id类型
void setPerson(id person) { [person setValue:@"Jason" forKey:@"name"]; [person setValue:@10 forKey:@"age"]; NSString *name = [person valueForKey:@"name"]; NSNumber *ageNumber = [person valueForKey:@"age"]; NSLog(@"Name:%@,Age:%@",name,[ageNumber stringValue]); }
Person *p = [[Person alloc] init]; setPerson(p);
因为形参是id,所以肯定不可以使用点语法。这里就可以使用KVC进行对象属性的赋值取值工作。
Situation Two: valueForKey & valueForKeyPath
Person *p = [[Person alloc] init]; p.name = @"Jason"; NSString *name = [p valueForKey:@"name"]; NSLog(@"Name:%@",name); p.card = [[Card alloc] init]; p.card.no = @"No.1"; NSString *cardId = [p valueForKeyPath:@"card.no"]; NSLog(@"Card Id:%@",cardId);valueForKey 可以直接取得对象属性的值;如果对象中的属性是其他对象,就可以使用valueForKeyPath访问属性对象中得某个属性值,如上例中的cord.no
Situation Three: For Array
Person *p = [[Person alloc] init]; p.name = @"Rose"; Person *p2 = [[Person alloc] init]; p2.name = @"Jack"; Person *p3 = [[Person alloc] init]; p3.name = @"Dog"; NSArray *ps = @[p,p2,p3]; NSArray *names = [ps valueForKey:@"name"]; [ps setValue:@"Tom" forKey:@"name"]; NSLog(@"names:%@",names);
通过KVC快速得到对象数组中某个属性的值的集合
NSArray *names = [ps valueForKey:@"name"];
通过KVC快速重置数组中所有对象的某个属性值
[ps setValue:@"Tom" forKey:@"name"];
实际应用场景举例:
默认的导航控制器上面的leftBarButtonItem和rightBarButtonItem的位置是不能调节位置的,这时我们可以通过KVC自定义UINavigationBar,然后实现自己想要的效果,大致代码如下
[self setValue:[[LFNavigationBar alloc] init] forKey:@"navigationBar"];这里的navigationBar是 UINavigationController 的只读属性,
@property(nonatomic,readonly) UINavigationBar *navigationBar;
是无法进行赋值操作的,但我们可以通过KVC进行修改操作。
3. 补充说明
setObject: forKey: 与 setValue: forKey:
NSMutableDictionary *dict = nil; // 字典赋值只能用setObject [dict setObject:@"Object" forKey:@"key"]; // 字典不能这样使用,是给KVC使用的 [dict setValue:@"Value" forKey:@"Key"];