常用方法
上一篇文章講了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},未去重。