KVC原理与数据筛选


作者:宋宏帅

1 前言

在技术论坛中看到一则很有意思的KVC案例:

  1. @interface Person : NSObject
  2. @property (nonatomic, copy) NSString *name;
  3. @property (nonatomic, assign) NSInteger age;
  4. @end
  5. Person *person = [Person new];
  6. person.name = @"Tom";
  7. person.age = 10;
  8. [person setValue:@"100" forKey:@"age"];//此处赋值为字符串,类中属性为Integer

第一反应是崩溃,因为OC是类型敏感的。可是自己实现并打印后的结果出于意料,没有崩溃且赋值成功。所以有了深入了解KVC的内部实现的想法!

@sum.self”];
NSNumberavg= [array valueForKeyPath:@”@avg.self”];
NSNumbermax= [array valueForKeyPath:@”@max.self”];
NSNumbermin= [array valueForKeyPath:@”@min.self”];

6 数据筛选

经过上面的分析可以明白KVC的真正执行流程。下面结合日常工程中的实际应用来优雅的处理数据筛选问题。使用KVC处理可以减少大量for的使用并增加代码可读性和健壮性。
如图所示:

项目中的细节如下:修改拒收数量时更新总妥投数和总拒收数、勾选明细更新总妥投数和总拒收数、全选、清空、反选。如果用通常的做法是每次操作都要循环去计算总数和记录选择状态。下面是采用KVC的实现过程。
模型涉及:

  1. @property (nonatomic,copy)NSString* skuCode;
  2. @property (nonatomic,copy)NSString* goodsName;
  3. @property (nonatomic,assign)NSInteger totalAmount;
  4. @property (nonatomic,assign)NSInteger rejectAmount;
  5. @property (nonatomic,assign)NSInteger deliveryAmount;
  6. ///单选用
  7. @property (nonatomic, assign) BOOL selected;

1)更新总数

  1. - (void)updateDeliveryInfo {
  2. //总数
  3. NSNumber *allDeliveryAmount = [self.orderDetailModel.deliveryGoodsDetailList valueForKeyPath:@"@sum.totalAmount"];
  4. //妥投数
  5. NSNumber *allRealDeliveryAmount = [self.orderDetailModel.deliveryGoodsDetailList valueForKeyPath:@"@sum.deliveryAmount"];
  6. //拒收数
  7. NSNumber *allRejectAmount = [self.orderDetailModel.deliveryGoodsDetailList valueForKeyPath:@"@sum.rejectAmount"];
  8. }

2)全选
[self.orderDetailModel.deliveryGoodsDetailList setValue:@(YES) forKeyPath:@”selected”];

3)清空
[self.orderDetailModel.deliveryGoodsDetailList setValue:@(NO) forKeyPath:@”selected”];

4)反选

  1. NSPredicate *selectedPredicate = [NSPredicate predicateWithFormat:@"selected == %@",@(YES)];
  2. NSArray *selectedArray = [self.orderDetailModel.deliveryGoodsDetailList filteredArrayUsingPredicate:selectedPredicate];
  3. NSPredicate *unSelectedPredicate = [NSPredicate predicateWithFormat:@"selected == %@",@(NO)];
  4. NSArray *unSelectedArray = [self.orderDetailModel.deliveryGoodsDetailList filteredArrayUsingPredicate:unSelectedPredicate];
  5. [selectedArray setValue:@(NO) forKeyPath:@"selected"];
  6. [unSelectedArray setValue:@(YES) forKeyPath:@"selected"];

7 总结

KVC在处理简单数据类型时会经过数据封装和拆装并转换为对应的数据类型。通过KVC的特性我们可以在日常使用中更加优雅的对数据进行筛选和处理。优点如下:可阅读性更高,健壮性更好。