iOS 关于KVC的简单知识

KVC(key-value coding),键值编码。指在iOS开发中,开发者可以通过属性名直接访问属性,给属性赋值或者取值,而不需要显式的调用setter和getter方法,这样就可以在运行时动态的访问和修改对象的属性。

KVC常用的四个方法

- (nullable id)valueForKey:(NSString *)key;                          //直接通过Key来取值
- (void)setValue:(nullable id)value forKey:(NSString *)key;          //通过Key来设值
- (nullable id)valueForKeyPath:(NSString *)keyPath;                  //通过KeyPath来取值
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;  //通过KeyPath来设值

valueForKey 和 setValue: forKey:的简单用法

我们都知道当一个对象的属性在声明文件(.h)中声明时,是可以用点语法访问并赋值的,但是如果声明在实现文件(.m)中,在外面用点语法是访问不到的,此时KVC就起到作用了

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface Book : NSObject
@end
#import "Book.h"
@interface Book()
@property (strong, nonatomic) NSString *name;
@property (assign, nonatomic) CGFloat price;
@end
@implementation Book
@end

//在控制器中实现下面代码
Book *book1 = [[Book alloc]init];
[book1 setValue:@"ios" forKey:@"name"];
[book1 setValue:@12 forKey:@"price"];
 NSString *name = [book1 valueForKey:@"name"];
 NSNumber *price = [book1 valueForKey:@"price"];
 NSLog(@"name = %@,price = %@",name,price.floatValue);

//打印结果如下
name = ios,price = 12.000000

这样以后我们自定义一些控件的时候访问私有属性就方便多了。 另外,我们还可以修改系统控件的内部属性,如我们自定义好一个tabbar,可以用下面的方式替换系统本来的UITabbar

 [self setValue:[[CustomTabbar alloc]init] forKey:@"tabBar"];

valueForKeypath 和 setValue:forKeypath: 的简单用法

当一个对象成为另一个对象的属性时,使用KVC就方便的多

#import <Foundation/Foundation.h>

@class Address;
@interface People : NSObject
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) Address *address;
@property (assign, nonatomic) NSInteger age;
@end

@interface Address : NSObject
@property (strong, nonatomic) NSString *contry;
@end

#import "People.h"
@interface People ()
@end
@implementation People
@end

@interface Address ()
@end
@implementation Address
@end

//在控制器中实现下面代码
Address *address = [[Address alloc]init];
address.contry = @"China";
People *people = [[People alloc]init];
people.address = address;
NSString *country1 = people.address.contry;
NSString *country2 = [people valueForKeyPath:@"address.contry"];
NSLog(@"1 = %@   2 = %@",country1,country2);
 
[people setValue:@"中国" forKeyPath:@"address.contry"];
country1 = people.address.contry;
country2 = [people valueForKeyPath:@"address.contry"]; NSLog(@"1 = %@   2 = %@",country1,country2);

KVC对于keyPath是搜索机制第一步就是分离key,用小数点.来分割key,然后再像普通key一样按照顺序搜索下去。

KVC 和 字典

常用的两个方法

- (NSDictionary<NSString *, id> *)dictionaryWithValuesForKeys:(NSArray<NSString *> *)keys;
- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues;
Addresss *add = [[Addresss alloc]init];
add.country = @"China";
add.province = @"Hebei";
add.city = @"Qinhuangdao";
add.district = @"Yanghedao";
NSArray *keys = @[@"country",@"province",@"city",@"district"];
//把对应key所有的属性全部取出来
NSDictionary *dict = [add dictionaryWithValuesForKeys:keys];
NSLog(@"dict = %@",dict);
    
//字典转模型
NSDictionary *modiDic = @{@"country":@"中国",@"province":@"河北省",@"city":@"秦皇岛市",@"district":@"洋河道"};
[add setValuesForKeysWithDictionary:modiDic];
NSLog(@"%@%@%@%@",add.country,add.province,add.city,add.district);

KVC处理非对象和自定义对象 (这里就不举例了!!!)

不是每一个方法都返回对象,但是valueForKey:总是返回一个id对象,如果原本的变量类型是值类型或者结构体,返回值会封装成NSNumber或者NSValue对象。这两个类会处理从数字,布尔值到指针和结构体任何类型。然后开以者需要手动转换成原来的类型。尽管valueForKey:会自动将值类型封装成对象,但是setValue:forKey:却不行。你必须手动将值类型转换成NSNumber或者NSValue类型,才能传递过去。

对于自定义对象,KVC也会正确地设值和取值。因为传递进去和取出来的都是id类型,所以需要开发者自己担保类型的正确性,运行时Objective-C在发送消息的会检查类型,如果错误会直接抛出异常。

KVC自带的运算

①简单集合运算符
@sum @avg @count @min @max 相信大家都知道这些运算符的意思

②对象运算符 返回值都是NSArray
@distinctUnionOfObjects //获取去重后的元素
@unionOfObjects//获取所有的元素

    Book *book1 = [[Book alloc]init];
    book1.name = @"ios";
    book1.price = 12;

    Book *book2 = [[Book alloc]init];
    book2.name = @"ios2";
    book2.price = 15;

    Book *book3 = [[Book alloc]init];
    book3.name = @"ios3";
    book3.price = 111;

    Book *book4 = [[Book alloc]init];
    book4.name = @"ios1";
    book4.price = 111;

    NSArray *arrBooks = @[book1,book2,book3,book4];
    NSNumber *sum = [arrBooks valueForKeyPath:@"@sum.price"];
    NSLog(@"sum = %f",sum.floatValue);
    NSNumber *avg = [arrBooks valueForKeyPath:@"@avg.price"];
    NSLog(@"avg = %f",avg.floatValue);
    NSNumber *count = [arrBooks valueForKeyPath:@"@count"];
    NSLog(@"count = %f",count.floatValue);
    NSNumber *min = [arrBooks valueForKeyPath:@"@min.price"];
    NSLog(@"min = %f",min.floatValue);
    NSNumber *max = [arrBooks valueForKeyPath:@"@max.price"];
    NSLog(@"max = %f",max.floatValue);
    
    NSLog(@"distinctUnionOfObjects");//获取去重后的元素
    NSArray *arrDistinch = [arrBooks valueForKeyPath:@"@distinctUnionOfObjects.price"];
    NSLog(@"arrDis = %@",arrDistinch);
    NSLog(@"UnionOfObjects");//获取所有元素
    NSArray *arrUnion = [arrBooks valueForKeyPath:@"@unionOfObjects.price"];
    NSLog(@"arrUnion = %@",arrUnion);

总结:KVC常用的两种用法就 对私有变量访问和赋值 和 字典转模型。
对于KVC如果你有好的见解欢迎随时指教!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容