iOS____浅谈KVC

2018-11-14  本文已影响0人  只青少年

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的人一点经验。不要说我给的博客都没有打印结果,个人认为,每个人应该在通过博客或者其他获取知识的途径之后,要有自己的实际操作和反思,这样得出来的结果和对知识点的体会才会更加深刻!!!

上一篇 下一篇

猜你喜欢

热点阅读