KVC简述:
KVC相信大家再熟悉不过了,键值编码,可以解决很多问题,包括视图上的给UITextField占位文字颜色大小进行设置,获取系统视图进行其颜色样式的自定义,模型转换等等,很多地方可以用KVC,接下来我们就深度解析总结一下KVC。 在iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值。而不需要调用明确的存取方法。这样就可以在运行时动态地访问和修改对象的属性。而不是在编译时确定,这也是iOS开发中的黑魔法之一。
KVC的使用
四个重要的方法:
- (nullable id)valueForKey:(NSString *)key; //直接通过Key来取值
- (void)setValue:(nullable id)value forKey:(NSString *)key; //通过Key来设值
- (nullable id)valueForKeyPath:(NSString *)keyPath; //通过KeyPath来取值
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath; //通过KeyPath来设值
简单的使用示例:
只有一层的:
#import "ViewController.h"
@interface ViewController ()
{
NSString *address; //成员变量
}
@property (nonatomic, copy) NSString *name; //属性
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//为属性赋值与取值
[self setValue:@"hui" forKey:@"name"]; //设置值
NSString *name = [self valueForKey:@"name"]; //获取值
NSLog(@"%@", name);
//为成员变量赋值与取值
[self setValue:@"Xiamen" forKey:@"address"]; //设置值
NSString *address = [self valueForKey:@"address"]; //获取值
NSLog(@"%@", address);
}
@end
多层(KeyPath):
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@end
NS_ASSUME_NONNULL_END
#import "Person.h"
@implementation Person
@end
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@property (nonatomic, strong) Person *person;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.person = [[Person alloc] init];
//为Preson的name属性赋值与取值(KeyPath)
[self setValue:@"hui" forKeyPath:@"person.name"];
NSString *name = [self valueForKeyPath:@"person.name"];
NSLog(@"%@", name);
}
@end
valueForKey:底层原理
原理如下:
- 先找相关方法 set:,_set:,setIs:,如果有,优先调用setter方法完成赋值(注意:set后面的键的第一字字母必须是大写!!)
- 如没有找到相关方法 + (BOOL)accessInstanceVariablesDirectly,判断是否可以直接方法成员变量
- 如果判断是NO,直接执行KVC的setValue:forUndefinedKey:(系统抛出异常,未定义key)
- 如果判断是YES,继续找相关的_,_is,,is
方法或成员 都不存在,setValue:forUndefinedKey:方法,默认抛出异常