前言:
上小节为大家介绍了kvc设值
的流程,这节为大家继续讲解一下kvc取值
的流程,其实流程和设值的方式差不多,大家可以按照上节课的代码测试流程来进行验证,这里就不为大家多做介绍了。
测试代码:
@interface JPerson : NSObject
@end
@implementation JPerson
{
NSString* name;
NSString* isName;
NSString* _name;
NSString* _isName;
}
- (id)init{
if(self = [super init])
{
name = @"1";
isName = @"2";
_name = @"3";
_isName = @"4";
}
return self;
}
- (id)getName{
return @"getName";
}
- (id)name{
return @"name";
}
- (id)_name{
return @"_name";
}
- (id)isName{
return @"isName";
}
+ (BOOL)accessInstanceVariablesDirectly{
return YES;
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
NSLog(@"%@‘s key is not founded --%s--",key,__func__);
}
- (id)valueForUndefinedKey:(NSString *)key{
NSLog(@"%@‘s value is not founded --%s--",key,__func__);
return [NSNull null];
}
@end
@interface JTestVC ()
@end
@implementation JTestVC
- (void)viewDidLoad {
[super viewDidLoad];
JPerson *person = [JPerson new];
NSString* value = [person valueForKey:@"name"];
NSLog(@"value = %@",value);
}
大家可以一次次地注释某段代码,来验证每一步的顺序。
得出结论:

扩展:
setValue:forKeyPath:
valueForKeyPath:
看以下的例子:
@interface Wallet : NSObject
@property(nonatomic , assign)int dollars;
@end
@implementation Wallet
@end
@interface Person : NSObject
@property(nonatomic , strong)Wallet* wallet;
@end
@implementation Person
- (id)init{
if(self = [super init]){
_wallet = [[Wallet alloc] init];
}
return self;
}
@end
@interface JTest2ViewController ()
@end
@implementation JTest2ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Person* xiaoming = [Person new];
[xiaoming setValue:@100 forKeyPath:@"wallet.dollars"];
NSNumber* dollars = (id)[xiaoming valueForKeyPath:@"wallet.dollars"];
NSLog(@"have %d dollars",[dollars intValue]);
// Do any additional setup after loading the view.
}
输出语句:
2021-01-06 15:56:37.028829+0800 TestDemo[21131:222598] have 100 dollars
是不是超级好用呀~~~~~~,跨路由的方式进行设置和取值
KVC 使用场景:
1、动态设值和取值
-
常用的可以通过
setValue:forKey:
和valueForKey:
-
也可以通过路由的方式
setValue:forKeyPath:
和valueForKeyPath:
2、通过KVC访问和修改私有变量
在日常开发中,对于类的私有属性
,在外部定义的对象,是无法直接访问私有属性的,但是对于KVC而言,一个对象没有自己的隐私,所以可以通过KVC修改和访问任何私有属性
3、多值操作(model和字典互转)
参考YYModel
4、修改一些系统空间的内部属性
在日常开发中,我们知道,很多UI控件都是在其内部由多个UI空间组合而成,这些内部控件苹果并没有提供访问的API,但是使用KVC可以解决这个问题,常用的就是自定义tabbar
、个性化UITextField中的placeHolderText
5.使用集合操作符取值
NSArray *score = @[@(89),@(80),@(20),@(56),@(89),@(100),@(89),@(89)];
NSLog(@"%@",[score valueForKeyPath:@"@count.self"]);//8
NSLog(@"%@",[score valueForKeyPath:@"@sum.self"]);//612
NSLog(@"%@",[score valueForKeyPath:@"@max.self"]);//100
NSLog(@"%@",[score valueForKeyPath:@"@min.self"]);//20
NSLog(@"%@",[score valueForKeyPath:@"@avg.self"]);//76.5
Person *person1 = [[Person alloc] init];
person1.name = @"王五";
person1.age = 10;
person1.position = @"学生";
Person *person2 = [[Person alloc] init];
person2.name = @"赵六";
person2.age = 19;
person2.position = @"学生";
Person *person3 = [[Person alloc] init];
person3.name = @"张三";
person3.age = 30;
person3.position = @"公司高管";
Person *person4 = [[Person alloc] init];
person4.name = @"李四";
person4.age = 25;
person4.position = @"软件开发";
Person *person5 = [[Person alloc] init];
person5.name = @"七七";
person5.age = 19;
person5.position = @"学生";
NSArray *personArr = @[person1,person2,person3,person4,person5];
NSLog(@"%@",[personArr valueForKeyPath:@"@distinctUnionOfObjects.age"]);
#输出结果为:10, 30, 19, 25(去重)
NSLog(@"%@",[personArr valueForKeyPath:@"@unionOfObjects.age"]);
#输出结果为:10, 19, 30,25, 19(没有去重)
网友评论