ios- KVC

首先放上官方文档:

https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueCoding_Protocol/index.html#//apple_ref/doc/uid/TP40003780

定义、解释:

KVC: Key Value Coding 键值编码

它是一种使用字符串标识符,间接访问对象属性的机制,而不是直接调用getter 和 setter方法。通常我们使用 valueForKey: 来替代getter 方法, setValue:forKey:来代替setter方法。

#import <Foundation/Foundation.h>
@class Book;
@interface Person : NSObject
     @property(nonatomic,copy)NSString *name;
     @property(nonatomic,assign) int age;
     @property(nonatomic,strong)Book *book;
@end

用法1:赋值、取值

    Person *p1=[[Person alloc] init];
    
    //通常写法,不使用KVC
    p1.age = 23;
    p1.name = @"Jordan";
    NSLog(@"%@",p1.hisName);
    //使用KVC
    [p1 setValue:@"Jordan" forKeyPath:@"name"];//赋值
    [p1 setValue:@"23" forKeyPath:@"age"];
    NSLog(@"%@",[hisValue valueForKey:@"name"]);//取值
         
    Person *p2=[[Person alloc]init];
    [p2 setValue:@"Mason" forKeyPath:@"name"];
    [p2 setValue:@"22" forKeyPath:@"age"];

注意:使用KVC间接修改对象属性时,系统会自动判断对象属性的类型,并完成转换。如上的 “23”

用法2:取值 自动进入对象内部

比如只生成name的数组:

//建立一个存储person对象的数组
        NSArray *persons=@[p1,p2];
        NSMutableArray *arrayM=[NSMutableArray array];
        //通常写法:
//        for (Person *p in persons) {
//            [arrayM addObject:[p valueForKeyPath:@"name"]];
//        }

    //KVC写法:
        [arrayM addObject:[persons valueForKeyPath:@"name"]];
        NSLog(@"%@",arrayM);

用法3:取值 层层深入:

Person *p1=[[Person alloc]init];
[p1 setValue:@"yangyong" forKeyPath:@"name"];
[p1 setValue:@"23" forKeyPath:@"age"];
Book *b1 = [[Book alloc] init];
b1.bookname = @"iPhone";
p1.book = b1;
         
Person *p2=[[Person alloc]init];
[p2 setValue:@"heyun" forKeyPath:@"name"];
[p2 setValue:@"22" forKeyPath:@"age"];
Book *b2 = [[Book alloc] init];
b2.bookname = @"ios";
p2.book = b2;
         
NSLog(@"%@%@", p1 , [p2  valueForKeyPath:@"name"]);
         
//建立一个存储person对象的数组,并打印
NSArray *persons=@[p1,p2];
NSLog(@"%@",persons);
 
NSArray *arrayM=[persons valueForKeyPath:@"book.bookname"];
NSLog(@"%@",arrayM);

总结 用法2 用法3

//只能获取对象属性的值
- (id)valueForKey:(NSString *)key;
//可以获取对象属性的属性的值(推荐使用)
- (id)valueForKeyPath:(NSString *)keyPath;

注意:KVC按照键值路径取值时,如果对象不包含指定的键值,会自动进入对象内部,层层深入,查找对象属性

另外:

模型--字典 互转

- (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;
//字典中的key 和对象属性要求一样

- (NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys;
//实例:
NSDictionary *dic = [self.dataArray dictionaryWithValuesForKeys:@[@"name",@"age"]];
for (int i =0 ; i<dic.count; i++) {
    NSLog(@"%@", [dic objectForKey:[dic allKeys][i]]);
}

用法4:KVC的消息传递

通过调用valueForKey:给容器中每一个对象发送操作消息,并且结果会被保存在一个新的容器中返回,这样我们能很方便地利用一个容器对象创建另一个容器对象。另外,valueForKeyPath:还能实现多个消息的传递。一个例子:

NSArray *array = [NSArray arrayWithObject:@"10.11",  
                                          @"20.22", nil];
NSArray *resultArray = [array valueForKeyPath:@"doubleValue.intValue"];  
NSLog(@"%@", resultArray);
/*打印结果
(
10,  
20  
)
*/

用法5:KVC容器操作

容器不仅仅能使用KVC方法实现对容器成员传递普通的操作消息,KVC还定义了特殊的一些常用操作,使用valueForKeyPath:结合操作符来使用,所定义的keyPath格式入下图所示

Left key path:如果有,则代表需要操作的对象路径(相对于调用者) 

Collection operator:以"@"开头的操作符 

Right key path:指定被操作的属性

常规操作符:

@avg、@count、@max、@min、@sum

(详见: http://nshipster.com/kvc-collection-operators/ )

对象操作符:

@distinctUnionOfObjects、@unionOfObjects

NSArray *values = [object valueForKeyPath:@"@unionOfObjects.value"];

@distinctUnionOfObjects操作符返回被操作对象指定属性的集合并做去重操作,而@unionOfObjects则允许重复。如果其中任何涉及的对象为nil,则抛出异常。


官网

取值:

- valueForKey:
- valueForKeyPath:
- dictionaryWithValuesForKeys:
- valueForUndefinedKey:
- mutableArrayValueForKey:
- mutableArrayValueForKeyPath:
- mutableSetValueForKey:
- mutableSetValueForKeyPath:
- mutableOrderedSetValueForKey:
- mutableOrderedSetValueForKeyPath:

赋值:

- setValue:forKeyPath:
- setValuesForKeysWithDictionary:
- setNilValueForKey:
- setValue:forKey:
- setValue:forUndefinedKey:


参考摘抄如下:

http://www.cnblogs.com/wendingding/p/3751279.html

http://www.tuicool.com/articles/2aYfy2

http://www.tuicool.com/articles/eA36Vr2

http://my.oschina.net/wolx/blog/361762?fromerr=APuNmaxZ


你可能感兴趣的:(ios,KVC)