iOS KVC详解

What is KVC

KVC 即 key-value coding,是一种间接访问对象属性的机制。这种机制是使用strings 来识别属性,而不是通过调用访问器方法或者是直接访问实例变量。很多时候在应用中使用KVC,可以简化编程。

KVC Fundamental

Keys 和 Key Paths的区别

Key是一个识别对象属性的字符串,一般与接收者对象的访问器方法名和实例变量名一致。Key必须实用 ASCII编码,小写字母开头,并且不能包含空格。例如buyer,amount,openingSource。
Key path是用点隔开的key的字符串,如address.street,先得到接收者对象的address属性,再判定address对象的street属性。

取值

       KVC可以用来访问三种不同类型的对象的值:attributes,to-one relationships, to-many relationships.
       attribute 指简单值的属性,如标量(质量、密度)、字符串,布尔值。 Value 对象如NSNumber 和其它一些可变类如NSColor也被认为是attrubutes。
       to-one relationship 的property:一对一关系的属性, 如NSView 实例的superview。
       to-many relationship:一对多关系的属性:由一个相关对象的集合组成 ,如一个NSArray或NSSet通常持有这样一个集合 。

例如新建Person,Dog,Book类,在Person类中:

#import <Foundation/Foundation.h>
#import "Dog.h"

@interface Person : NSObject{
@private int _height;
}

@property (nonatomic,copy) NSString *name;  //attribute
@property (nonatomic,assign) NSInteger age; //attribute
@property (nonatomic,retain) Dog *dog;      //to-one relationship
@property (nonatomic,retain) NSArray *books;//to-many relationship

- (void)printInfo;
@end

Book类:

#import <Foundation/Foundation.h>

@interface Book : NSObject
@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign)float price;
@end

使用:

NSArray *books = @[b1,b2];//只能创建不可改变的数组
    p1.books = books;

    [p1.books enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        Book *tmp = (Book *)obj;
        NSLog(@"%@",tmp.name);
    }];//枚举方式遍历取值

    //KVC方式
    NSArray *book_names = [p1 valueForKeyPath:@"books.name"];
    NSLog(@"KVCbook列表%@",book_names);
    //可使用KVC提供的@avg,@count,@max,@min,@sum
    NSNumber *totalPrice = [p1 valueForKeyPath:@"books.@sum.price"];
    NSLog(@"%@",totalPrice);

    NSNumber *avgPrice   = [p1 valueForKeyPath:@"books.@avg.price"];
    NSLog(@"%@",avgPrice);
改值
//根据之前提到过的,再次体悟forKey 与 forKeyPath的差异
    p1.dog = d;
    p1.name = @"Kerry";
    [p1 setValue:@99 forKeyPath:@"height"];

    d.name = @"dog";
    NSLog(@"%@",p1.dog.name);
    [p1 setValue:@"dog1" forKeyPath:@"dog.name"];
    NSLog(@"%@",p1.dog.name);
    [p1 setValue:@"dog2" forKey:@"dog.name"];//这是不可以的
    /**
     *当对象又引用其它对象的时候,直接给其他对象赋值必须用forKeyPath
     **/
    [p1.dog setValue:@"dog2" forKey:@"name" ];
    NSLog(@"%@",p1.dog.name);
    /**
     *用KVC取值
    **/
//    NSLog(@"%@",[p1 valueForKey:@"dog.name"]);
    NSLog(@"%@",[p1 valueForKeyPath:@"dog.name"]);
    NSLog(@"%@",[p1.dog valueForKeyPath:@"name"]);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值