valueForKeyPath详解

1.objectForKey/valueForKey/valueForKeyPath区分

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

2.用处一

2.1. 对于@[@{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];
输出结果:
  city:(
    "北京",
    "上海",
    "深圳"
  )
  count:(
    22,
    18,
    17
  )

3.用处二

3.1. 可以计算平均值/求和等操作(简单集合运算符分别为:@avg,@count,@max,@min,@sum)
例如:求 例2.1 中数组的算术操作(数组是对象的话,需要使用' @sum.count ',count为求值字段 )
    NSLog(@"求和:%@",[arr valueForKeyPath:@"@sum.count"]);
    NSLog(@"平均:%@",[arr valueForKeyPath:@"@avg.count"]);
    NSLog(@"最大:%@",[arr valueForKeyPath:@"@max.count"]);
    NSLog(@"最小:%@",[arr valueForKeyPath:@"@min.count"]);
输出结果:
[15:29:27] -[LoginViewController Test] [第83行] 求和:57
[15:29:27] -[LoginViewController Test] [第84行] 平均:19
[15:29:27] -[LoginViewController Test] [第85行] 最大:22
[15:29:27] -[LoginViewController Test] [第86行] 最小:17

例如:数组是非对象,可以如下求值,floatValue为求值的类型
    NSMutableArray *array = [NSMutableArray arrayWithObjects:@9,@"12",@15,@20,@"30", nil];
    CGFloat maxValue = [[array valueForKeyPath:@"@max.floatValue"] floatValue];
    CGFloat minValue = [[array valueForKeyPath:@"@min.floatValue"] floatValue];
输出结果:
[16:22:55] -[LoginViewController Test] [第122行] 最大值=== 30.000000 
[16:22:55] -[LoginViewController Test] [第122行] 最小值 === 9.000000

再或者如下:使用self求值默认为double类型数据
    NSArray *array2 = @[@0, @2, @3, @4, @7];
    NSNumber *sum = [array2 valueForKeyPath:@"@sum.self"];
    NSNumber *avg = [array2 valueForKeyPath:@"@avg.self"];
    NSNumber *max = [array2 valueForKeyPath:@"@max.self"];
    NSNumber *min = [array2 valueForKeyPath:@"@min.self"];

4.用处三

4.1. 对于@{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"]);
输出结果:
[15:32:33] -[LoginViewController Test] [第93行] 小明
[15:32:33] -[LoginViewController Test] [第94行] 22

5.用处四

5.1. 不只是字典套字典,对象套对象/对象套对象再套字典等情况,都可以通过链式调用到深层的值
例如:
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

6.用处五

6.1. 可以快速删除数组重复数据
例如:如果数组是非对象对局,使用的keypath为 ' @distinctUnionOfObjects.self '
NSArray *array3 = @[@"qq", @"wechat", @"qq", @"msn", @"wechat"];
NSLog(@"%@", [array3 valueForKeyPath:@"@distinctUnionOfObjects.self"]);
输出结果:
[15:36:55] -[LoginViewController Test] [第97行] (
    qq,
    wechat,
    msn
)
例如:数组是对象的数据,使用的keypath为 ' @distinctUnionOfObjects.keys ',keys为去重的键值
NSArray *array = @[ @{@"title":@"zxp",@"name":@"zhangxiaoping"}, 
@{@"title":@"zxp2",@"name":@"zhangxiaoping2"}, 
@{@"title":@"zxp",@"name":@"zhangxiaoping3"}, @{@"title":@"zxp",@"name":@"zhangxiaoping"}];
//根据name字段,来进行重复删除。
NSArray *newArray = [array valueForKeyPath:@"@distinctUnionOfObjects.name"];
//如果要根据title字段来删除重名的写法为`@distinctUnionOfObjects.title` 
NSLog(@"%@", newArray);
输出结果:
[15:42:37] -[LoginViewController Test] [第105行] (
    zhangxiaoping3,
    zhangxiaoping2,
    zhangxiaoping
)

7.用处六

7.1. 可以进行示例方法的调用
NSArray *array = @[@"name", @"w", @"aa", @"ZXPing"]; 
NSLog(@"%@", [array valueForKeyPath:@"uppercaseString"]);
输出结果:
(
    NAME,
    W,
    AA,
    ZXPING
)
相当于数组中的每个成员执行了uppercaseString方法,然后把返回的对象组成一个新数组返回。
既然可以用uppercaseString方法,那么NSString的其他方法也可以,
比如[array valueForKeyPath:@"length"]。当然,其他对象的实例方法也可以以此类推来进行调用~!
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容

  • 今年年初的时候,支付宝搞了一个集五福的活动,女朋友让我给她发福,晚上时候一直拖朋友加我支付宝好友,找了很多朋友才把...
    宁小南阅读 1,114评论 0 0
  • 1861年,两位科学家卷入了一场绝妙的争论。具体来说,他们对语言和记忆在人类大脑中的运作有着相反的想法。尔宁斯特....
    JuliaJia_a671阅读 714评论 1 2