深入探索KVC
来源:互联网 发布:淘宝网天猫全棉女卫衣 编辑:程序博客网 时间:2024/06/11 16:31
顺便解释一下KVO和KVC
在学习完iOS时,或许我们经常对KVO和KVC产生迷惑,不能够非常清楚的区分KVC与KVO之间的关系,此处声明二者使用时没有直接的联系。小编简单做一下区别:
KVO key-value-observe是一种设计模式,它观察对象的某一个属性的变化KVC key-value-coding 是一种间接访问对象成员属性的的方法,可以通过该方法间接修改或获取对象的属性值 二者主要区别:KVO侧重观察值得变化,KVC侧重对数据的读取
下面重点介绍KVC
- 为了更加清楚解释我先创建了两个类
// BGWork#import <Foundation/Foundation.h>@class BGCompany;@interface BGWorker : NSObject{ NSString *name; NSInteger age; NSString *gender; BGCompany *company; NSArray *fellows; @private NSString *address;}@property (nonatomic, readonly, copy) NSString *number;@end#import "BGWorker.h"@implementation BGWorker@end// BGCompany#import <Foundation/Foundation.h>@interface BGCompany : NSObject{ NSString *companyName; NSString *ID;}@end#import "BGCompany.h"@implementation BGCompany@end
- 最简单的KVC,直接调用方法赋值
/* - (void)setValue:(nullable id)value forKey:(NSString *)key; */ BGWorker *worker = [[BGWorker alloc]init]; // 赋值操作 [worker setValue:@"zhangsan" forKey:@"name"]; [worker setValue:@12 forKey:@"age"]; [worker setValue:@"男" forKey:@"gender"]; // 取值操作 NSString *name = [worker valueForKey:@"name"]; NSNumber *age = [worker valueForKey:@"age"]; NSString *gender = [worker valueForKey:@"gender"]; NSLog(@"name = %@ age = %@ gender = %@", name, age, gender);
- 复杂对象作为成员变量,对复杂对象成员变量赋值
此时需要用到另一个方法,关联keyPath
/* - (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath; */ BGCompany *company = [[BGCompany alloc]init]; // 复杂对象赋值 [worker setValue:company forKey:@"company"]; // 根据路径赋值 [worker setValue:@"leliankeji" forKeyPath:@"company.companyName"]; [worker setValue:@"213432423" forKeyPath:@"company.ID"]; // 根据路径取值 NSString *companyName = [worker valueForKeyPath:@"company.companyName"]; NSString *ID = [worker valueForKeyPath:@"company.ID"]; NSLog(@"company:%@ - %@", companyName, ID);
- KVC的高级用法,如果对象内的数组中存放的也是同一类型的某种复杂对象,则可以对该对象的某一属性执行一定操作。比如,求和,计数,最大值,最小值
BGWorker *work1 = [[BGWorker alloc]init]; [work1 setValue:@"13" forKeyPath:@"age"]; BGWorker *work2 = [[BGWorker alloc]init]; [work2 setValue:@"14" forKeyPath:@"age"]; BGWorker *work3 = [[BGWorker alloc]init]; [work3 setValue:@"15" forKeyPath:@"age"]; NSArray *arr = [NSArray arrayWithObjects:work1, work2, work3, nil]; [worker setValue:arr forKeyPath:@"fellows"]; NSLog(@"%@", [worker valueForKey:@"fellows"]); NSLog(@"%@", [worker valueForKeyPath:@"fellows.age"]); // 获取数组内每个对象的age NSLog(@"%@", [worker valueForKeyPath:@"fellows.@count.age"]); // 数组含有年龄属性的元素个数 NSLog(@"%@", [worker valueForKeyPath:@"fellows.@sum.age"]); // 数组内所有元素age的和 NSLog(@"%@", [worker valueForKeyPath:@"fellows.@avg.age"]); // 平均值 NSLog(@"%@", [worker valueForKeyPath:@"fellows.@min.age"]); // 最小值 NSLog(@"%@", [worker valueForKeyPath:@"fellows.@max.age"]); // 最大值
- 另一种KVC,对对象整体赋值
/* - (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues; */ NSDictionary *dic = @{@"name": @"lisi", @"age" : @"21", @"gender" :@"男", @"fellows" :@[work1, work2, work3], @"company" :company }; BGWorker *worker2 = [[BGWorker alloc]init]; [worker2 setValuesForKeysWithDictionary:dic]; NSLog(@"%@", [worker2 valueForKey:@"name"]); NSLog(@"%@", [worker2 valueForKey:@"age"]); NSLog(@"%@", [worker2 valueForKey:@"gender"]); NSLog(@"%@", [worker2 valueForKey:@"fellows"]); NSLog(@"%@", [worker2 valueForKeyPath:@"company.companyName"]); NSLog(@"%@", [worker2 valueForKeyPath:@"company.ID"]);
发现
- 如果成员变量是自定义对象,还会触发成员变量的setValuesForKeyWithDictionary:方法,该对象的各个成员变量也会被赋值。
- 如果一个类不去写成属性,也不实现getter setter 方法我们依然可以通过KVC访问他的成员属性,
- 通过KVC我们还可以访问私有属性(呵呵,绝对独家),此处证明私有属性不提供外部接口依然可以读写(前提必须知道成员变量名,即key)
[worker setValue:@"北京" forKey:@"address"]; NSLog(@"##%@##", [worker valueForKey:@"address"]);
4. readOnly 可以使用KVC赋值(这也是独家哦)
// 只读重置值 [worker setValue:@"13260318431" forKey:@"number"]; NSLog(@"%@", [worker valueForKey:@"number"]);
源码地址
0 0
- 深入探索KVC
- ios KVC内部机制探索
- ios-KVC深入
- 深入理解 KVC 实现机制
- 深入理解KVC与KVO
- iOS学习笔记: 初步探索KVC & KVO
- 深入理解 KVC\KVO 实现机制 — KVC
- 深入理解 KVC\KVO 实现机制 — KVC
- 深入理解 KVC\KVO 实现机制 — KVC
- 深入探索透视投影变换
- 深入探索sizeof
- 深入探索Servlet
- 深入探索透视投影变换
- 深入探索正交投影变换
- 深入探索透视投影变换
- 深入探索透视投影变换
- struct用法深入探索
- 深入探索透视投影变换
- Jenkins with XCode 持续化集成(原创)
- poj 1252 Euro Efficiency 正负完全背包
- 在ScrollView中嵌套ListView
- SQL行转列
- Lookup Transformation(2) 优化
- 深入探索KVC
- 前端优化总结--编码习惯(一)
- 如何比拼好货做的更好
- 双边滤波(bilateral filter)彩色图 matlab实现代码
- @Column
- java23.IO操作------使用Apache IO库操作IO与文件
- M0、M3、M4简单对比
- WIndows下MySQL Zip版本安装
- ORACLE水位线讲解