KVC基本使用

Keys
key 是一个字符串,它定义了一个对象的一个属性,一个key相当于存取器的名字或者接受者的实例变量Keys必须使用ASCII编码,以小写字母开始不包含空白
例如:name amount

Key Paths
A key path is a string of dot separated keys that is used to specify a sequence of object properties to traverse. The property of the first key in the sequence is relative to the receiver, and each subsequent key is evaluated relative to the value of the previous property.
例如 关键路径 address.street将从接受对象获得address的值,然后确定相对于address对象的street属性

(2)使用KVC获得属性值
valueForKey:返回特定键的值,如果该键没有存取器或者变量实例,接受者向自身发送一个valueForUndefineKey:消息,
valueForKeyPath:返回特定键路径的值,在键路径序列中的任一对象如果对于键没有合适的值将接受valueForUndefineKey:消息

如何使用KVC存取对象属性呢?看个示例
1、使用KVC
定义一个Student类,继承于NSObject。
.h文件

#import <Foundation/Foundation.h>   

 @interface Student : NSObject   
 {   
       NSString *name;   
 }   
@end  

.m文件

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

.m文件没有任何实现。name属性没有加property,原来的访问方法就访问不了name属性了。怎么办呢?用kvc就可以了

 #import "Student.h"   
 int main(int argc, const char * argv[])   
{   
  @autoreleasepool {   
    Student *student = [[[Student alloc]init ]autorelease];   
    [student setValue:@"张三" forKey:@"name"];   
    NSString *name = [student valueForKey:@"name"];   
    NSLog(@"学生姓名:%@",name);   
   }   
return 0;   
 }   

打印结果:
2012-07-20 15:04:09.920 objectiveC[1977:403] 学生姓名:张三
张三 这个值存进去了,通过valueForKey取出来了。
如果存的时候key和类属性的名称不一致会怎么样呢?

2、键路径访问属性
如果访问这个类的属性中的属性呢?那就用到了键路径
关键字:键路径取值valueForKeyPath 键路径存值:forKeyPath
新建一个类Course,课程类,课程类有课程名称这个属性
.h文件

 #import <Foundation/Foundation.h>   

 @interface Course : NSObject   
{   
    NSString *CourseName;   
 }   
 @end 

.m文件

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

在Student中添加Course属性 ,student.h文件中代码如下:

  #import <Foundation/Foundation.h>   
  @class Course;   
  @interface Student : NSObject   
 {   
     NSString *name;   
     Course *course;   
 }   
 @end   

实现还是什么都没有,这里就不贴代码了
在main方法中,我们实验通过键路径访问Course中CourseName的属性

#import "Student.h"   
#import "Course.h"   
int main(int argc, const char * argv[])   
{   
  @autoreleasepool {   
    Student *student = [[[Student alloc]init ]autorelease];   
    [student setValue:@"张三" forKey:@"name"];   
    NSString *name = [student valueForKey:@"name"];   
    NSLog(@"学生姓名:%@",name);   

    Course *course = [[[Course alloc]init] autorelease];   
    [course setValue:@"语文课" forKey:@"CourseName"];   
    [student setValue:course forKey:@"course"];   
    NSString *courseName = [student    valueForKeyPath:@"course.CourseName"];   
    NSLog(@"课程名称:%@", courseName);   

    //也可以这样存值   
    [student setValue:@"数学课" forKeyPath:@"course.CourseName"];   
    courseName = [student valueForKeyPath:@"course.CourseName"];   
    NSLog(@"课程名称:%@", courseName);   

}   
return 0;   
 }   

运行打印结果:
2012-07-20 15:33:51.902 objectiveC[2415:403] 学生姓名:张三
2012-07-20 15:33:51.904 objectiveC[2415:403] 课程名称:语文课
2012-07-20 15:33:51.904 objectiveC[2415:403] 课程名称:数学课
3、自动封装基本数据类型
我们在Student类中添加分数属性 NSInteger point;
.h文件

 #import <Foundation/Foundation.h>   
 @class Course;   
@interface Student : NSObject   
{   
    NSString *name;   
    Course *course;   
    NSInteger point;   
}   
@end 

.m文件不改变就不管了

下面是main示例了

 #import "Student.h"   
 #import "Course.h"   

 int main(int argc, const char * argv[])   
{   
  @autoreleasepool {   
    Student *student = [[[Student alloc]init ]autorelease];   
    [student setValue:@"张三" forKey:@"name"];   
    NSString *name = [student valueForKey:@"name"];   
    NSLog(@"学生姓名:%@",name);   

    Course *course = [[[Course alloc]init] autorelease];   
    [course setValue:@"语文课" forKey:@"CourseName"];   
    [student setValue:course forKey:@"course"];   
    NSString *courseName = [student valueForKeyPath:@"course.CourseName"];   
    NSLog(@"课程名称:%@", courseName);   

    //也可以这样存值   
    [student setValue:@"数学课" forKeyPath:@"course.CourseName"];   
    courseName = [student valueForKeyPath:@"course.CourseName"];   
    NSLog(@"课程名称:%@", courseName);   

    [student setValue:@"88" forKeyPath:@"point"];   
    NSString *point = [student valueForKey:@"point"];   
    NSLog(@"分数:%@", point);   

}   
return 0;   
}   

打印结果:
2012-07-20 15:43:19.593 objectiveC[2533:403] 学生姓名:张三
2012-07-20 15:43:19.596 objectiveC[2533:403] 课程名称:语文课
2012-07-20 15:43:19.596 objectiveC[2533:403] 课程名称:数学课
2012-07-20 15:43:19.598 objectiveC[2533:403] 分数:88
我们用NSString*类型设置的属性值@”88”,而我们的属性是NSInteger类型的,存取都没有问题。
4、操作集合
在Student类中加入数组NSArray,用来表示其他的学生。这样我们可以添加多个其他的学生,再用集合操作计算学生的分数,最高分,最低分,平均分等

   #import <Foundation/Foundation.h>   
   @class Course;   
   @interface Student : NSObject   
{   
    NSString *name;   
    Course *course;   
    NSInteger point;   
    NSArray *otherStudent;   
 }   
@end  

.m文件实现不变。

在main函数中添加三个学生,添加到数组中,然后求平均分,最高,最低分,学生数量

 #import "Student.h"    
 #import "Course.h"   
int main(int argc, const char * argv[])   
{   
  @autoreleasepool {   
    Student *student = [[[Student alloc]init ]autorelease];   
    [student setValue:@"张三" forKey:@"name"];   
    NSString *name = [student valueForKey:@"name"];   
    NSLog(@"学生姓名:%@",name);   

    [student setValue:@"88" forKey:@"point"];   
    NSString *point = [student valueForKey:@"point"];   
    NSLog(@"分数:%@", point);   

    Student *student1 = [[[Student alloc]init]autorelease];   
    Student *student2 = [[[Student alloc]init]autorelease];   
    Student *student3 = [[[Student alloc]init]autorelease];   
    [student1 setValue:@"65" forKey:@"point"];   
    [student2 setValue:@"77" forKey:@"point"];   
    [student3 setValue:@"99" forKey:@"point"];   
    NSArray *array = [NSArray arrayWithObjects:student1,student2,student3,nil];   
    [student setValue:array forKey:@"otherStudent"];   
    NSLog(@"其他学生的成绩%@", [student valueForKeyPath:@"otherStudent.point"]);   
    NSLog(@"共%@个学生", [student valueForKeyPath:@"otherStudent.@count"]);   
    NSLog(@"最高成绩:%@", [student valueForKeyPath:@"otherStudent.@max.point"]);   
    NSLog(@"最低成绩:%@", [student valueForKeyPath:@"otherStudent.@min.point"]);   
    NSLog(@"平均成绩:%@", [student valueForKeyPath:@"otherStudent.@avg.point"]);   
}   
return 0;   
}   

运行打印结果
2012-07-20 16:09:17.101 objectiveC[2857:403] 学生姓名:张三
2012-07-20 16:09:17.104 objectiveC[2857:403] 分数:88
2012-07-20 16:09:17.105 objectiveC[2857:403] 其他学生的成绩(
65,
77,
99
)
2012-07-20 16:09:17.106 objectiveC[2857:403] 共3个学生
2012-07-20 16:09:17.106 objectiveC[2857:403] 最高成绩:99
2012-07-20 16:09:17.107 objectiveC[2857:403] 最低成绩:65
2012-07-20 16:09:17.108 objectiveC[2857:403] 平均成绩:80.3333333333333333333
还可以求总和 @sum。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员的修养

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值