我们知道,许多编程技术都基于间接机制,包括整个面向对象编程领域。现在我们来了解一下一种间接机制,这种机制不属于Objective-C语言的特性,而是Cocoa提供的一种特性。键/值编码(Key-value-coding)是一种间接更改对象状态的方式,许多人亲切地称其为KVC,其实现方法时使用字符串表示要更改的对象状态。看看博主学习KVC机制时用到的代码(有关方法实现在代码注释里有说明):
Student.h
#import <Foundation/Foundation.h>
@interface Student : NSObject
{
NSString *name;
int age;
float height;
float weight;
}
@property NSString *name;
@property int age;
@property float height;
@property float weight;
@end
Student.m
#import "Student.h"
@implementation Student
@synthesize name;
@synthesize age;
@synthesize height;
@synthesize weight;
-(NSString *)description
{
NSString *st = [[NSString alloc] initWithFormat:@"name = %@,age = %d,height = %.2f,weight = %.2f",name,age,height,weight];
return st;
}
@end
Info.h
#import <Foundation/Foundation.h>
@class Student;
@interface Info : NSObject
{
NSMutableArray *student;
}
-(void)addStu:(Student *)stu;
-(void)print;
@end
Info.m
#import "Info.h"
@implementation Info
-(void)addStu:(Student *)stu
{
if (student == nil) {
student = [[NSMutableArray alloc] init];
}
[student addObject:stu];
}
-(void)print
{
NSLog(@"student:%@",student);
}
@end
main.m
#import <Foundation/Foundation.h>
#import "Student.h"
#import "Info.h"
//因为Objective-C是一种C语言,所以可以使用函数
Student *display(NSString *name,int age,float height,float weight)
{
Student *stu = [[Student alloc] init];
stu.name = name;
stu.age = age;
stu.height = height;
stu.weight = weight;
return stu;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
Info *infor = [[Info alloc] init];
Student *stu;
stu = display(@"xiaojin", 23, 166.00, 105.00);
//使用valueForKey:获取stu对象中name属性值
NSString *name1 = [stu valueForKey:@"name"];
NSLog(@"name1:%@",name1);
[infor addStu:stu];
stu = display(@"xiaobo", 30, 165.00, 110.10);
//使用valueForKey:获取stu对象中age属性值
NSLog(@"age:%@",[stu valueForKey:@"age"]);//NSLog中的%@是用来输出对象的,但是age是一个int值,而不是对象。对于KVC,Cocoa会自动装箱和开箱标量值,仅KVC具有这种装箱和开箱功能,常规方法调用和属性语法不具备这种功能
NSLog(@"stu:%@",stu);
//除了检索值外,还可以使用-setValue:forKey:方法依据名称设置值
[stu setValue:@"xiaobobo" forKey:@"name"];
NSLog(@"Now,stu:%@",stu);
[infor addStu:stu];
stu = display(@"xiaohong", 22, 156.00, 95.00);
//使用valueForKey:获取stu对象中height属性值
NSNumber *height1 = [stu valueForKey:@"height"];
NSLog(@"height1:%@",height1);
[infor addStu:stu];
[infor print];
//KVC中,键路径不仅能引用对象值,还可以引用一些运算符来进行一些运算:让我们来看看快速运算吧
//计算student数组中的元素个数
NSNumber *count;
count = [infor valueForKeyPath:@"student.@count"];
NSLog(@"We have %@ student",count);
//统计student中元素的重量的总和
NSNumber *sum;
sum = [infor valueForKeyPath:@"student.@sum.weight"];
NSLog(@"All weight are %@",sum);
//计算student中元素的重量的平均值
NSNumber *avgWeight;
avgWeight = [infor valueForKeyPath:@"student.@avg.weight"];
NSLog(@"The average of weight is %@",avgWeight);
//统计student中元素的重量的最小值和最小值
NSNumber *min,*max;
min = [infor valueForKeyPath:@"student.@min.weight"];
max = [infor valueForKeyPath:@"student.@max.weight"];
NSLog(@"The weight of student:min = %@,max = %@",min,max);
//获取数组中各个元素的人名字
NSArray *names;
names = [infor valueForKeyPath:@"student.@distinctUnionOfObjects.name"];
NSLog(@"name:%@",names);
}
return 0;
}