iOS____浅谈KVC
kvc的定义
KVC(Key-value coding)键值编码,就是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值。而不需要调用明确的存取方法。这样就可以在运行时动态地访问和修改对象的属性。而不是在编译时确定,这也是iOS开发中的黑魔法之一。很多高级的iOS开发技巧都是基于KVC实现的。
KVC的定义都是对NSObject的扩展来实现的,Objective-C中有个显式的NSKeyValueCoding类别名,所以对于所有继承了NSObject的类型,都能使用KVC(一些纯Swift类和结构体是不支持KVC的,因为没有继承NSObject),下面是KVC最为重要的四个方法:
- (nullableid)valueForKey:(NSString*)key;
- (void)setValue:(nullableid)value forKey:(NSString*)key;
- (nullableid)valueForKeyPath:(NSString*)keyPath;
- (void)setValue:(nullableid)value forKeyPath:(NSString*)keyPath;
项目应用示例
1.先新建一个Person类,继承与NSObject,以下是Person类的.h文件和.m文件的内容.
Person.h
@interface Book : NSObject
@property (nonatomic,copy) NSString * name;
@end
@interface Person : NSObject
@property (nonatomic,strong) Book * book;//Book类
@property (nonatomic,copy,readonly) NSString * name;//只读属性的姓名
@property (nonatomic,assign) NSInteger age;
@end
Person.m
@interface Person (){
NSString* dog;
}
@end
@implementation Person
- (void)printSomeStr{
NSLog(@"print Some Str");
}
@end
@implementation Book
@end
2.在VC中对person的属性和方法用KVC进行简单的赋值和调用
- (void)testKVC{
/*
KVC破坏person类的只读属性的特性.,使得只读属性name能够通过KVC的方式进行属性值的更改
*/
Person* person = [[Personalloc]init];
[personsetValue:@"潘鹏飞"forKey:@"name"];
NSLog(@"name = %@",person.name);
/*
* KVC可以给person类中未公开的实例对象进行赋值并获取这个实例对象
* KVC也可以执行person类中未公开的方法名。
* 如下:
*/
[person setValue:@"小狗"forKey:@"dog"];
NSLog(@"dog = %@",[personvalueForKey:@"dog"]);
[personvalueForKey:@"printSomeStr"];
/*
KVC有自动装箱(自动类型转换)的功能,我们不需要转换类型。所以,可以直接把字符串123赋值给person属性age(nsinteger)类型。
*/
[person setValue:@"123"forKey:@"age"];
NSLog(@"age = %ld",(unsignedlong)person.age);
/*
KVC支持键值路径,说白了就是直尺嵌套。比如,book是person的属性,可以通过kvc通过路径用person对象对book的属性name进行赋值.
*/
Book* book = [[Bookalloc]init];
person.book= book;
[person setValue:@"钢铁是怎样炼成的"forKeyPath:@"book.name"];
NSLog(@"book.name = %@",[person valueForKeyPath:@"book.name"]);
/*
KVC给model赋值,同时也能解决赋值的时候,若dic中的key占用了系统的关键字,可以进行替换掉不和系统关键字冲突的属性名
*/
NSDictionary* dic =@{@"id":@"我的id"};
Model* model = [[Modelalloc]initWithDic:dic];
NSLog(@"id = %@",model.my_id);
}
model.h文件
@interface Model : NSObject
@property (nonatomic,copy) NSString * my_id;
- (instancetype)initWithDic:(NSDictionary*)dic;
@end
model.m文件
@implementation Model
- (instancetype)initWithDic:(NSDictionary*)dic
{
self= [superinit];
if(self) {
[self setValuesForKeysWithDictionary:dic];
}
return self;
}
/*如果model的某个属性和系统的冲突了,就可以换一个属性来处理,比如id*/
- (void)setValue:(id)value forUndefinedKey:(NSString*)key{
if([keyisEqualToString:@"id"]) {
self.my_id= value;
}
}
@end
以上就是我自己个人对kvc的一点理解,希望能够帮助初次接触kvc的人一点经验。不要说我给的博客都没有打印结果,个人认为,每个人应该在通过博客或者其他获取知识的途径之后,要有自己的实际操作和反思,这样得出来的结果和对知识点的体会才会更加深刻!!!