常用方法
上一篇文章讲了KVC最基本的知识,只涉及了下面2个方法:
- (nullable id)valueForKey:(NSString*)key; //取属性值
- (void)setValue:(nullableid)value forKey:(NSString*)key;//设置属性值
下面有2个与其类似的方法:
- (nullable id)valueForKeyPath:(NSString*)keyPath; //取属性值
- (void)setValue:(nullableid)value forKeyPath:(NSString*)keyPath;//设置属性值
这两个方法会根据keyPath中用“.”分隔的key按顺序定位到属性,如下:
@interface Cat: NSObject
@property (nonatomic, copy ) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
@interface Person: NSObject
@property (nonatomic, strong) Cat *pet;
@end
Person *person = [[Person alloc] init];
//设置person.pet的name值
[person setValue:@"Tom" forKeyPath:@"pet.name"];
//取person.pet的age值
NSNumber *age = [person valueForKeyPath:@"pet.age"];
上面的方法都只能操作单一属性,下面2个方法能同时作用于多个属性:
- (NSDictionary<NSString *, id> *)dictionaryWithValuesForKeys:(NSArray<NSString *> *)keys;
- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues;
顾名思义,这2个方法就是根据给的key集合以字典形式返回对应的值和根据跟定的字典设置属性值。
集合运算
在使用valueForKeyPath且属性为集合类时,可以在keyPath中嵌入集合运算。集合运算是由符号“@”和跟在后面的一些特定关键字组成,通常都是操作在keyPath中跟在其后面的属性。运算可分为三类,以下面的数据为例:
@interface Person: NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSDate *birthday;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, copy) NSArray<Person *> *contacts;
@end
假设Jerry的contacts中有3个联系人,如下表格
name | birthday | age |
---|---|---|
John | 1985-04-06 | 33 |
Tom | 1992-01-25 | 26 |
John | 2001-03-07 | 17 |
- 聚合运算
@avg:取集合中所有元素,返回它们的算数平均值
@sum:取集合中所有元素,返回它们相加的值
@max:取集合中所有元素,返回它们的最大值
@min:取集合中所有元素,返回它们的最下值
@count:返回集合中元素的数量,keyPath中其后不需要跟属性
NSNumber *ageAvg = [Jerry valueForKeyPath:@"contacts.@avg.age"]; //25.33
NSNumber *ageSum = [Jerry valueForKeyPath:@"contacts.@sum.age"]; //76.00
NSNumber *ageMax = [Jerry valueForKeyPath:@"contacts.@max.age"]; //33
NSNumber *birthdayMin = [Jerry valueForKeyPath:@"contacts.@min.birthday"]; //1985-04-06
NSNumber *count = [Jerry valueForKeyPath:@"contacts.@count"]; //3
@max和@min会调用集合中元素的compare:方法,对于自定义类,你可以自己实现compare:方法。
- 数组运算
@distinctUnionOfObjects:取集合中所有元素,返回去重后的数组
@unionOfObjects:取集合中所有元素,返回未去重的数组
NSArray *distinctContacts = [Jerry valueForKeyPath:@"contacts.@distinctUnionOfObjects.name"];
NSArray *contacts = [Jerry valueForKeyPath:@"contacts.@unionOfObjects.name"];
distinctContacts的结果是{John, Tom},去掉了一个重复的John。
contacts的结果是{John, Tom, John},未去重。
- 嵌套运算
该运算针对的是集合中的元素也是集合的情况
@distinctUnionOfArrays:取集合中所有集合的所有元素,返回去重后的数组
@unionOfArrays:取集合中所有集合的所有元素,返回未重的数组
@distinctUnionOfSets:取集合中所有集合的所有元素,返回去重后的集合,和distinctUnionOfArrays不同的是返回的是NSSet而非NSArray。
NSArray *array = @[Jerry, Jerry];
NSArray *distinctContacts = [array valueForKeyPath:@"contacts.@distinctUnionOfArrays.name"];
NSArray *contacts = [Jerry valueForKeyPath:@"contacts.@unionOfArrays.name"];
distinctContacts的结果是{John, Tom},去掉了3个重复的John和1个重复Tom。
contacts的结果是{John, Tom, John,John, Tom, John},未去重。