*********书接上回⛰:我们继续来学习KVC:*********
列举一些常用的操作实例:
- 1:Key-Value Coding (KVC) : 基本类型
Person *person = [[Person alloc] init];
[person setValue:@"小华" forKey:@"name"];
[person setValue:@24 forKey:@"age"];
[person setValue:@"王" forKey:@"familyName"];
NSLog(@"%@ - %@ - %@",[person valueForKey:@"name"],[person valueForKey:@"age"],[person valueForKey:@"familyName"]);
- 2:KVC - 集合类型
person.array = @[@"1",@"2",@"3"];
// 由于不是可变数组 - 无法做到
// person.array[0] = @"100";
NSArray *array = [person valueForKey:@"array"];
// 用 array 的值创建一个新的数组
array = @[@"100",@"2",@"3"];
[person setValue:array forKey:@"array"];
NSLog(@"%@",[person valueForKey:@"array"]);
// KVC 的方式可变数组来进行操作
NSMutableArray *ma = [person mutableArrayValueForKey:@"array"];
ma[0] = @"100";
NSLog(@"%@",[person valueForKey:@"array"]);
- 3 :KVC - 集合操作符
字典的操作:
NSDictionary* dict = @{
@"name":@"Cooci",
@"nick":@"KC",
@"subject":@"iOS",
@"age":@18,
@"length":@180
};
LGStudent *p = [[LGStudent alloc] init];
// 字典转模型
[p setValuesForKeysWithDictionary:dict];
NSLog(@"%@",p);
// 键 数组 转 模型 到字典--->( 从模型里面取固定的几个属性 ,转成字典)
NSArray *array = @[@"name",@"age"];
NSDictionary *dic = [p dictionaryWithValuesForKeys:array];
NSLog(@"%@",dic);
2020-02-11 22:23:19.289802+0800 001-KVC简介[9704:888351] <LGStudent: 0x600003aaa370>
2020-02-11 22:23:19.291332+0800 001-KVC简介[9704:888351] {
age = 18;
name = Cooci;
}
#pragma mark - array取值
- (void)arrayDemo{
LGStudent *p = [LGStudent new];
p.penArr = [NSMutableArray arrayWithObjects:@"pen0", @"pen1", @"pen2", @"pen3", nil];
NSArray *arr = [p valueForKey:@"penArr"]; // 动态成员变量
NSLog(@"pens = %@", arr);
//NSLog(@"%@",arr[0]);
NSLog(@"%d",[arr containsObject:@"pen9"]);
// 遍历
NSEnumerator *enumerator = [arr objectEnumerator];
NSString* str = nil;
while (str = [enumerator nextObject]) {
NSLog(@"%@", str);
}
}
#pragma mark - KVC消息传递
- (void)arrayMessagePass{
NSArray *array = @[@"Hank",@"Cooci",@"Kody",@"CC"];
NSArray *lenStr= [array valueForKeyPath:@"length"];
NSLog(@"lenStr=%@",lenStr);=(
4,
5,
4,
2
)
// 消息从array传递给了string
// uppercaseString lowercaseString
// 全部小写
NSArray *lowStr= [array valueForKeyPath:@"lowercaseString"];
NSLog(@"lowStr=%@",lowStr);=(
hank,
cooci,
kody,
cc
)
// 全部大写
NSArray *upStr= [array valueForKeyPath:@"uppercaseString"];
NSLog(@"upStr=%@",upStr); =(
HANK,
COOCI,
KODY,
CC
)
}
#pragma mark - 聚合操作符
// @avg、@count、@max、@min、@sum
- (void)aggregationOperator{
NSMutableArray *personArray = [NSMutableArray array];
for (int i = 0; i < 6; i++) {
LGStudent *p = [LGStudent new];
NSDictionary* dict = @{
@"name":@"Tom",
@"age":@(18+i),
@"nick":@"Cat",
@"length":@(175 + 2*arc4random_uniform(6)),
};
[p setValuesForKeysWithDictionary:dict];
[personArray addObject:p];
}
NSLog(@"%@", [personArray valueForKey:@"length"]);
/// 平均身高
float avg = [[personArray valueForKeyPath:@"@avg.length"] floatValue];
NSLog(@"%f", avg);
// 个数
int count = [[personArray valueForKeyPath:@"@count.length"] intValue];
NSLog(@"%d", count);
// 求和
int sum = [[personArray valueForKeyPath:@"@sum.length"] intValue];
NSLog(@"%d", sum);
// 最大值
int max = [[personArray valueForKeyPath:@"@max.length"] intValue];
NSLog(@"%d", max);
// 最小值
int min = [[personArray valueForKeyPath:@"@min.length"] intValue];
NSLog(@"%d", min);
}
// 数组操作符 @distinctUnionOfObjects @unionOfObjects
- (void)arrayOperator{
NSMutableArray *personArray = [NSMutableArray array];
for (int i = 0; i < 6; i++) {
LGStudent *p = [LGStudent new];
NSDictionary* dict = @{
@"name":@"Tom",
@"age":@(18+i),
@"nick":@"Cat",
@"length":@(175 + 2*arc4random_uniform(6)),
};
[p setValuesForKeysWithDictionary:dict];
[personArray addObject:p];
}
NSLog(@"%@", [personArray valueForKey:@"length"]);
// 返回操作对象指定属性的集合
NSArray* arr1 = [personArray valueForKeyPath:@"@unionOfObjects.length"];
NSLog(@"arr1 = %@", arr1);
// 返回操作对象指定属性的集合 -- 去重
NSArray* arr2 = [personArray valueForKeyPath:@"@distinctUnionOfObjects.length"];
NSLog(@"arr2 = %@", arr2);
}
// 嵌套集合(array&set)操作 @distinctUnionOfArrays @unionOfArrays @distinctUnionOfSets
- (void)arrayNesting{
NSMutableArray *personArray1 = [NSMutableArray array];
for (int i = 0; i < 6; i++) {
LGStudent *student = [LGStudent new];
NSDictionary* dict = @{
@"name":@"Tom",
@"age":@(18+i),
@"nick":@"Cat",
@"length":@(175 + 2*arc4random_uniform(6)),
};
[student setValuesForKeysWithDictionary:dict];
[personArray1 addObject:student];
}
NSMutableArray *personArray2 = [NSMutableArray array];
for (int i = 0; i < 6; i++) {
LGStudent *person = [LGStudent new];
NSDictionary* dict = @{
@"name":@"Tom",
@"age":@(18+i),
@"nick":@"Cat",
@"length":@(175 + 2*arc4random_uniform(6)),
};
[person setValuesForKeysWithDictionary:dict];
[personArray2 addObject:person];
}
// 嵌套数组
NSArray* nestArr = @[personArray1, personArray2];
NSArray* arr = [nestArr valueForKeyPath:@"@distinctUnionOfArrays.length"];
NSLog(@" 去重之后的数组arr = %@", arr);
NSArray* arr1 = [nestArr valueForKeyPath:@"@unionOfArrays.length"];
NSLog(@"组合之后的所以元素的数组 = %@", arr1);
}
数组运算符
数组运算符导致valueForKeyPath:返回一个对象数组,该对象数组与右键路径指示的一组特定对象相对应。
@distinctUnionOfObjects :删除重复的元素
@unionOfObjects:不会删除重复元素
#pragma mark NSSet 嵌套操作
- (void)setNesting{
NSMutableSet *personSet1 = [NSMutableSet set];
for (int i = 0; i < 6; i++) {
LGStudent *person = [LGStudent new];
NSDictionary* dict = @{
@"name":@"Tom",
@"age":@(18+i),
@"nick":@"Cat",
@"length":@(175 + 2*arc4random_uniform(6)),
};
[person setValuesForKeysWithDictionary:dict];
[personSet1 addObject:person];
}
NSLog(@"personSet1 = %@", [personSet1 valueForKey:@"length"]);
NSMutableSet *personSet2 = [NSMutableSet set];
for (int i = 0; i < 6; i++) {
LGPerson *person = [LGPerson new];
NSDictionary* dict = @{
@"name":@"Tom",
@"age":@(18+i),
@"nick":@"Cat",
@"length":@(175 + 2*arc4random_uniform(6)),
};
[person setValuesForKeysWithDictionary:dict];
[personSet2 addObject:person];
}
NSLog(@"personSet2 = %@", [personSet2 valueForKey:@"length"]);
// 嵌套set
NSSet* nestSet = [NSSet setWithObjects:personSet1, personSet2, nil];
// 交集
NSArray* arr1 = [nestSet valueForKeyPath:@"@distinctUnionOfSets.length"];
NSLog(@"arr1 = %@", arr1);
}
嵌套运算符
嵌套运算符对嵌套集合进行操作,其中集合本身的每个条目都包含一个集合。
@distinctUnionOfArrays:当您指定@distinctUnionOfArrays运算符时,valueForKeyPath:创建并返回一个数组,该数组包含与右键路径指定的属性相对应的所有集合的组合的不同对象。
@unionOfArrays:当您指定@unionOfArrays运算符时,将valueForKeyPath:创建并返回一个数组,该数组包含与右键路径指定的属性相对应的所有集合的组合的所有对象,而不会删除重复项。
@distinctUnionOfSets:当您指定@distinctUnionOfSets运算符时,将valueForKeyPath:创建并返回一个NSSet对象,该对象包含与右键路径指定的属性相对应的所有集合的组合中的不同对象。
该运算符的行为类似于@distinctUnionOfArrays,不同之处在于它期望NSSet包含NSSet对象实例而不是NSArray实例实例的NSArray实例。同样,它返回一个NSSet实例。假设示例数据已存储在集合中而不是数组中,则示例调用和结果与所示相同@distinctUnionOfArrays。
-
4:访问非对象属性 --结构体
通过NSObject使用对象和非对象属性提供的键值编码协议方法的默认实现。默认实现自动在对象参数或返回值与非对象属性之间转换。即使存储的属性是标量或结构,这也允许基于键的getter和setter的签名保持一致。
#pragma mark 4:访问非对象属性 --结构体
- (void)threeFloats{
LGPerson *person = [[LGPerson alloc] init];
// 您可以threeFloats使用键值编码设置值:
ThreeFloats floats = {1., 2., 3.};
NSValue *value = [NSValue valueWithBytes:&floats objCType:@encode(ThreeFloats)];
[person setValue:value forKey:@"threeFloats"];
// 您可以threeFloats通过键值编码获得值:
NSValue *reslut = [person valueForKey:@"threeFloats"];
NSLog(@"%@",reslut);
// 默认实现是valueForKey:调用threeFloats getter,然后返回包装在NSValue对象中的结果。
// 默认实现使用getValue:消息解包该值,然后setThreeFloats:使用结果结构进行调用。
ThreeFloats th;
[reslut getValue:&th] ;
NSLog(@"%f - %f - %f",th.x,th.y,th.z);
}
- 5 多层访问
#pragma mark 5:多层访问
- (void)doubleFind{
LGPerson *person = [[LGPerson alloc] init];
LGStudent *student = [[LGStudent alloc] init];
student.subject = @"iOS";
person.student = student;
[person setValue:@"大师班" forKeyPath:@"student.subject"];
NSLog(@"%@",[person valueForKeyPath:@"student.subject"]);
}