13.键-值编码(KVC)

1.键值编码的基本概念(KVC)

  1. 键-值编码是一个用于间接访问对象属性的机制,使用该机制不需要调用存取方法和变量实例就可以访问对象属性 .(声明为private也可以访问)
  2. 键-值编码方法在Objective-C非正式协议(类目)NSKeyValueCoding中被声明,默认的实现方法有NSObject提供
  3. 键-值编码支持带有对象的属性,同时也支持纯数值类型和结构 .非对象参数和返回类型会被识别并自动封装/解封

2.KVC的基本用法

  1. 设置和访问:
    1) 键-值编码中的基本调用包括-valueForKey: 和-setValue: forKey: 这两个方法,他们以字符串飞形式向对象发送消息 , 字符串使我们关注属性的关键 .
    2) 是否存在setter , getter方法,如果不存在,他将在内部查找名位_key或key的实例变量. 通过KVC , 可以获取不存在getter方法的对象值,无需通过对象指针直接访问.
    3) 需要注意的是,当我们通过setValue: forKey: 设置对象的值,或通过valueForKey来获取对象的值时, 如果对象的实例变量为基本数据类型时(char , int , float , BOOL),我们需要对数据进行封装 .
  2. 路径: 除了通过键值外,键-值编码嗨支持指定路径,像系统文件一样,用”.”号隔开.
  3. 一对多的关系: 如果向NSArray请求一个键值, 它实际上会查询数组中的每个对象来查找这个键值, 然后将查询结果打包到另一个数组中并返回给你.
  4. KVC的简单运算: sum, min, max, avg, count

3.实例一

Book.h和Book.m文件

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

@interface Book : NSObject
{
@private
    NSString *_name;
    Author *_author;    //书的作者
    NSArray *_relativeBooks; //相关的书籍
    float price;        //书的价格
}
@end

#import "Book.h"
@implementation Book
@end

Author.h和Author.m文件

#import <Foundation/Foundation.h>

@interface Author : NSObject {
@private
    NSString *_name;
}
@end

#import "Author.h"
@implementation Author
@end

main.m文件

Book *book = [[Book alloc] init];
Author *author = [[Author alloc] init];
//注意forKey后面的NSString不能写错,如果错运行时才会crash
[author setValue:@"jack" forKey:@"_name"];
//基本数据类型需要封装一下
[book setValue:[NSNumber numberWithFloat:12.6] forKey:@"price"];
NSNumber *price = [book valueForKeyPath:@"price"];
NSLog(@"%@",price);//--->12.6

//键值访问(直接访问)
[book setValue:@"ipad develper" forKey:@"name"];
[book setValue:author forKey:@"_author"];
//路径访问(间接访问)其中的.不是点语法,而是路径
[book setValue:@"tom" forKeyPath:@"author.name"];//直接访问
NSString *authorName = [book valueForKeyPath:@"_author._name"];
NSLog(@"%@",authorName);//--->tom

//一对多的关系
NSMutableArray *releBooks = [NSMutableArray arrayWithCapacity:3];
for (int i=0; i<3; i++) {
    Book *book = [[Book alloc] init];
    NSString *name = [NSString stringWithFormat:@"job_%d",i];
    [book setValue:name forKey:@"_name"];

    [book setValue:@(12+i) forKey:@"price"];
    [releBooks addObject:book];
    [book release];
}
[book setValue:releBooks forKey:@"_relativeBooks"];
//拿到所有书籍的name的两种方法:间接访问和直接访问
NSArray *names = [book valueForKeyPath:@"_relativeBooks._name"];
NSLog(@"%@",names);//--->("job_0","job_1","job_2")
NSArray *names = [releBooks valueForKeyPath:@"_name"];
NSLog(@"%@",names);//--->("job_0","job_1","job_2")

//运算,运算的字段必须是数值类型NSNumber或者基本数据类型,计算的结果是NSNumber
//运算关键字sum、min、max、avg、count
NSNumber *sum = [book valueForKeyPath:@"_relativeBooks.@avg.price"];
NSLog(@"sum: %@",sum);//--->sum: 13

4.实例二

定义一个Person对象,他叫乔布斯,他有去多苹果设备: 一个macbook, 价格8000; 一个iPhone, 价格5000; 一个iPad, 价格3800; 使用KVC为Person设置名字,使用KVC计算乔布斯所有设备的总价
Person.h和Person.m文件

#import <Foundation/Foundation.h>
@interface Person : NSObject {
@private
    NSString *name;
    NSArray *apples;
}
@end

#import "Person.h"
@implementation Person
@end

AppleDevice.h和AppleDevice.m文件

#import <Foundation/Foundation.h>
@interface AppleDevice : NSObject {
@private
    NSString *_name;
    float _price;
}
@end

#import "AppleDevice.h"
@implementation AppleDevice
@end

main.m文件

AppleDevice *mac = [[AppleDevice alloc] init];
[mac setValue:@"macbook" forKey:@"_name"];
[mac setValue:@8000 forKey:@"_price"];
AppleDevice *iphone = [[AppleDevice alloc] init];
[iphone setValue:@"iphone" forKey:@"_name"];
[iphone setValue:@5000 forKey:@"_price"];
AppleDevice *ipad = [[AppleDevice alloc] init];
[ipad setValue:@"ipad" forKey:@"_name"];
[ipad setValue:@3800 forKey:@"_price"];

NSArray *apples = @[mac,iphone,ipad];
[ipad release];
[mac release];
[iphone release];

Person *p = [[Person alloc] init];
[p setValue:@"乔布斯" forKey:@"name"];
[p setValue:apples forKey:@"apples"];
NSNumber *sum = [p valueForKeyPath:@"apples.@sum._price"];
NSLog(@"sum: %@",sum);//--->sum: 16800
[p release];
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值