神奇的valueForKeyPath

以前一直没有用到过valueForKeyPath,一直以为和valueForKey差不多,可是今天一看才吓了一跳,功能好强大啊.


objectForKey/valueForKey/valueForKeyPath区分

objectForKey是NSDictionary的一个方法,用来通过key取得字典的值.只有字典可以调用这个方法
valueForKeyvalueForKeyPath是两个KVC方法,所有的对象都可以调用, valueForKey可以通过属性名获取到这个属性的值,而valueForKeyPath则可以实现多级取值.

功能一

对于@[@{key:value},@{key:value},@{key:value}]的数组(数组元素是字典的),通过同一个key可以取到value的集合(数组)

    NSDictionary *dic1 = @{@"city":@"北京",@"count":@"22"};
    NSDictionary *dic2 = @{@"city":@"上海",@"count":@"18"};
    NSDictionary *dic3 = @{@"city":@"深圳",@"count":@"17"};
    
    NSArray *arr = @[dic1,dic2,dic3];
    
    NSLog(@"city:%@",[arr valueForKeyPath:@"city"]);
    NSLog(@"count:%@",[arr valueForKeyPath:@"count"]);

输出结果:

2016-08-03 15:07:05.276 ValueForKeyPath使用[5181:192059] city:(
    "北京",
    "上海",
    "深圳"
)
2016-08-03 15:07:05.276 ValueForKeyPath使用[5181:192059] count:(
    22,
    22,
    18,
    17
)

功能二

针对功能一,还有增强版,可以计算平均值/求和等操作

    NSLog(@"求和:%@",[arr valueForKeyPath:@"@sum.count"]);
    NSLog(@"平均:%@",[arr valueForKeyPath:@"@avg.count"]);
    NSLog(@"最大:%@",[arr valueForKeyPath:@"@max.count"]);
    NSLog(@"最小:%@",[arr valueForKeyPath:@"@min.count"]);

输出结果

2016-08-03 15:07:05.277 ValueForKeyPath使用[5181:192059] 求和:79
2016-08-03 15:07:05.278 ValueForKeyPath使用[5181:192059] 平均:19.75
2016-08-03 15:07:05.278 ValueForKeyPath使用[5181:192059] 最大:22
2016-08-03 15:07:05.278 ValueForKeyPath使用[5181:192059] 最小:17

功能三

对于@{key1:@{key2:vale}}的字典(字典的value是另一个字典),通过key1.key2的链式的方式得到最深层的字典的值

    NSDictionary *dict4 = @{@"name":@"小明",@"age":@"22"};
    NSDictionary *dict5 = @{@"student":dict4};
    NSDictionary *dict6 = @{@"class":dict5};
    NSDictionary *dict7 = @{@"school":dict6};
    
    NSLog(@"%@",[dict7 valueForKeyPath:@"school.class.student.name"]);
    NSLog(@"%@",[dict7 valueForKeyPath:@"school.class.student.age"]);

输出结果

2016-08-03 15:07:05.278 ValueForKeyPath使用[5181:192059] 小明
2016-08-03 15:07:05.279 ValueForKeyPath使用[5181:192059] 22

功能四

针对于功能三,不只是字典套字典,对象套对象/对象套对象再套字典等情况,都可以通过链式调用到深层的值

    Student *student1 = [[Student alloc] init];
    student1.name = @"小红";
    student1.info = @{@"phone":@"13102212345",@"mail":@"xiaohong@qq.com"};
    
    School *school = [[School alloc] init];
    school.student = student1;
    
    NSLog(@"%@",[school valueForKeyPath:@"student.name"]);
    NSLog(@"%@",[school valueForKeyPath:@"student.info.phone"]);

输出结果

2016-08-03 15:21:38.258 ValueForKeyPath使用[5261:202278] 小红
2016-08-03 15:21:38.258 ValueForKeyPath使用[5261:202278] 13102212345
2016-08-03 15:21:38.259 ValueForKeyPath使用[5261:202278] xiaohong@qq.com
Demo代码

ViewController.m

#import "ViewController.h"
#import "Student.h"
#import "School.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSDictionary *dic1 = @{@"city":@"北京",@"count":@"22"};
    NSDictionary *dic2 = @{@"city":@"上海",@"count":@"18"};
    NSDictionary *dic3 = @{@"city":@"深圳",@"count":@"17"};
    
    NSArray *arr = @[dic1,dic2,dic3];
    
    NSLog(@"city:%@",[arr valueForKeyPath:@"city"]);
    NSLog(@"count:%@",[arr valueForKeyPath:@"count"]);
    NSLog(@"求和:%@",[arr valueForKeyPath:@"@sum.count"]);
    NSLog(@"平均:%@",[arr valueForKeyPath:@"@avg.count"]);
    NSLog(@"最大:%@",[arr valueForKeyPath:@"@max.count"]);
    NSLog(@"最小:%@",[arr valueForKeyPath:@"@min.count"]);
    
    NSDictionary *dict4 = @{@"name":@"小明",@"age":@"22"};
    NSDictionary *dict5 = @{@"student":dict4};
    NSDictionary *dict6 = @{@"class":dict5};
    NSDictionary *dict7 = @{@"school":dict6};
    
    NSLog(@"%@",[dict7 valueForKeyPath:@"school.class.student.name"]);
    NSLog(@"%@",[dict7 valueForKeyPath:@"school.class.student.age"]);
    
    Student *student1 = [[Student alloc] init];
    student1.name = @"小红";
    student1.info = @{@"phone":@"13102212345",@"mail":@"xiaohong@qq.com"};
    
    School *school = [[School alloc] init];
    school.student = student1;
    
    NSLog(@"%@",[school valueForKeyPath:@"student.name"]);
    NSLog(@"%@",[school valueForKeyPath:@"student.info.phone"]);
    NSLog(@"%@",[school valueForKeyPath:@"student.info.mail"]);
}
@end

Student.h

#import <Foundation/Foundation.h>

@interface Student : NSObject
@property(nonatomic,strong) NSDictionary *info;
@property(nonatomic,strong) NSString *name;
@end

School.h

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

@interface School : NSObject
@property(nonatomic,strong) Student *student;
@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • KVC(Key-value coding)键值编码,单看这个名字可能不太好理解。其实翻译一下就很简单了,就是指iO...
    朽木自雕也阅读 1,591评论 6 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,933评论 18 139
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,774评论 0 9
  • 1、memcache的概念? Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨...
    桖辶殇阅读 2,271评论 2 12
  • 1. redis的五大数据类型 String(字符串): String 是redis最基本的数据类型,一个key对...
    AD甜蜜蜜阅读 1,306评论 0 2