本片文章主要讲解,KVC的实现原理、注意细节、实际应用:
KVC原理、KVC赋值和取值,KVC的key、keyPath注意点、KVC的集合处理、数模转换。
这里先创建两个对象,用于下面的举例应用
#import
@interface Author : NSObject{ NSString *_name; //作者出版的书籍,一个作者对应多个书籍对象 NSArray *_issueBook; } @end //--------------------- #import "Author.h" @implementation Author @end
#import <Foundation/Foundation.h> #import "Author.h" @interface Book : NSObject{ Author *_author; } //名字 @property(nonatomic,copy) NSString *name; ///价格 @property(nonatomic,assign)float price; @end //--------------------- #import "Book.h" @implementation Book @end
1、KVC原理
首先,两张图带你去了解,KVC的赋值和取值的原理:
1.1、setValue:forKey:的赋值原理
accessInstanceVariablesDirectly方法的默认返回值是YES,如下: + (BOOL)accessInstanceVariablesDirectly { return YES; }
1.2、valueForKey:的取值原理
2、KVC赋值
通过键值路径为对象的属性赋值。一般用于私有的属性赋值:
//---------- KVC键值编码 -------- Author *author = [[Author alloc] init]; //设置属性值 [author setValue:@"莫言" forKey:@"name"];
如果对象A中的属性含有是一个对象B,设置对象B的属性必须使用 forKeyPath 方法:
//------- KVC设置作者的书籍数组 ------- //键值路径:对于一个类中有数组对象的属性进行便捷操作 Book *book1 = [[Book alloc] init]; book1.name = @"红高粱"; book1.price = 9; Book *book2 = [[Book alloc] init]; book2.name = @"蛙"; book2.price = 6; NSArray *array = [NSArray arrayWithObjects:book1,book2, nil]; [author setValue:array forKeyPath:@"issueBook"];
3、KVC取值与集合处理
通过键值路径获取属性的值。一般通过key值获得私有属性的值。
//获取属性值 NSString *name = [author valueForKey:@"name"]; NSLog(@"%@",name);
可以通过keypath获得值:
// ----- KVC中键值路径取值 ------- //基本数据类型会自动被包装成NSNumber,装到数组中 //得到所有书籍的价格 NSArray *priceArray = [author valueForKeyPath:@"issueBook.price"]; NSLog(@"%@",priceArray); //获取数组的大小 NSNumber *count = [author valueForKeyPath:@"issueBook.@count"]; NSLog(@"count=%@",count); //获取书籍价格的总和 NSNumber *sum = [author valueForKeyPath:@"issueBook.@sum.price"]; NSLog(@"%@",sum); //获取书籍的平均值 NSNumber *avg = [author valueForKeyPath:@"issueBook.@avg.price"]; NSLog(@"%@",avg); //获取书籍的价格最大值和最小值 NSNumber *max = [author valueForKeyPath:@"issueBook.@max.price"]; NSNumber *min = [author valueForKeyPath:@"issueBook.@min.price"]; NSLog(@"%@____%@",max,min);
4、Key 与 KeyPath 的区别
1、赋值 setValue:forKey: 方法,取值 valueForKey: 方法
Key:键值,只能赋值当前层访问当前层。
2、赋值 setValue:forKeyPath: 方法,取值 valueForKeyPath:方法
KeyPath:键值路径,可以多层赋值多层访问。
5、模型转换
将字典转型成Model,方法:setValuesForKeysWithDictionary:
///数模转换 -(void)dicToModel{ // 定义一个字典 NSDictionary *dict = @{ @"name" : @"rattan", @"price" : @"88.66", }; // 创建模型 Book *p = [[Book alloc] init]; // 字典转模型 [p setValuesForKeysWithDictionary:dict]; NSLog(@"\n作者:%@\n价格:%.2lf",p.name,(float)p.price); }
打印结果:
注意:字典的key和Model的属性必须一一对应。 否则系统会报错如下:
‘[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key name.’