zoukankan      html  css  js  c++  java
  • Objective

    KVC的使用


    1、KVC 全称 key valued coding 键值编码

    反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性.JAVA,C#都有这个机制。ObjC也有,所以你根部不必进行任何操作就可以进行属性的动态读写,就是KVC。

    KVC的操作方法由NSKeyValueCoding提供,而他是NSObject的类别,也就是说ObjC中几乎所有的对象都支持KVC操作。

    2、常用方法

    获取值的方法

    valueForKey:,传入NSString属性的名字。

    valueForKeyPath:,传入NSString属性的路径,xx.xx形式。

    valueForUndefinedKey它的默认实现是抛出异常,可以重写这个函数做错误处理。

    那么问题来了 现在有连个类,Book类(对应属性:name,prices)和Person类(对应属性:name,height,Book *book),person有一本名字叫做《太阳的后裔》,那么现在想通过KVC给这本书赋值,应该如何操作?

    个人总结答案:因为现在想修改的不是对应类也就是Person类的属性,是要修改Book的属性(person.book),所以需要通过valueForKeyPath来进行修改^_^                     

                                   


    修改值的方法

    setValue:forKey:

    setValue:forKeyPath:

    setValue:forUndefinedKey:

     setValue:forKey的搜索过程:

    1. 用@property定义的属性的key值(这里指的是property 系统生成的setter、getter方法 )
    2. setter方法的key值(用户自定义的setter方法)
    3. 直接访问成员变量,先找key,如果找不到,再找_key
    4. 以上三种都未找到就会调用- (void)setValue:(id)value forUndefinedKey:(NSString *)key 方法。
    5. 如果没有重写setValue:forUndefinedKey程序会马上崩溃。

    注意:

    1、使用KVC间接修改对象属性时,系统会自动判断对象属性的类型,并完成转换。

    2、KVC可以访问成员变量,无论是否提供getter/setter方法,无论可见性是怎样,是否有readonly修饰。

     setValue:forUndefinedKey与valueForUndefinedKey的应用

    KVC的主要用途无非是ORM映射,就是将dictionary转换成model,但有些服务器返回的字段有可能是oc的关键字比如‘id’,’description’等。如上代码举得id的例子,我们无法让@property后面key值为id,于是使用大写的ID代替,KVC是区分大小写的我们不用担心。这时我们只需在setValue:forUndefinedKey把id的key值赋值给ID的key值,就可以避免关键字的尴尬。 

    3、dict <->model 互转

    字典转模型

    [self setValuesForKeysWithDictionary:dict];

    模型转字典

    [p dictionaryWithValuesForKeys:array];

    4、KVC集合

    NSArray/NSSet等都支持KVC

    [array valueForKeyPath:@"dog.name"];

    5、使用KVC计算属性

    格式为:[p valueForKeyPath:@"Left keypath部分.@Collectionoperator部分.Right keypath部分”];

    Left keypath部分:需要操作对象路径。

    Collectionoperator部分:通过@符号确定使用的集合操作。

    Right keypath部分:需要进行集合操作的属性。

    举例:[p valueForKeyPath:@"books.@sum.price"];

    @avg:平均值

    @count:总数

    @max:最大

    @min:最小

    @sum:总数

    6、具体代码与实际编辑

    1)当使用KVC给对象的属性赋值时,当根据输入的Key值没有找到对应的Value时调用

    1 - (void)setValue:(id)value forUndefinedKey:(NSString *)key {
    2     
    3     NSLog(@"key = %@没有找到",key);
    4     
    5 }

    2)当找到了对应的key值,代码为

     1 //
     2 //  main.m
     3 //  KVC熟悉与加强
     4 //
     5 //  Created by ma c on 16/5/16.
     6 //  Copyright © 2016年 彭盛凇. All rights reserved.
     7 //
     8 
     9 #import <Foundation/Foundation.h>
    10 
    11 #import "Model.h"
    12 
    13 int main(int argc, const char * argv[]) {
    14     @autoreleasepool {
    15         
    16         Model *model =  [[Model alloc] init];
    17         
    18         [model setValue:@"Coder丶PSS" forKey:@"name"];
    19         [model setValue:@"178" forKeyPath:@"height"];
    20         
    21 //        NSLog(@"%@",model);
    22         
    23         NSLog(@"名字叫%@,身高为%@",[model valueForKey:@"name"],[model valueForKey:@"height"]);
    24         
    25         
    26         
    27     }
    28     return 0;
    29 }

    结果为:

    3)使用原生方法解析数据

    因为本人没有服务器,写了个假数据(plist),进行解析,效果是一样的

    (1)plist:

    (2)解析数据代码

     model.m

     1 //
     2 //  Model.h
     3 //  KVC熟悉与加强
     4 //
     5 //  Created by ma c on 16/5/16.
     6 //  Copyright © 2016年 彭盛凇. All rights reserved.
     7 //
     8 
     9 #import <Foundation/Foundation.h>
    10 
    11 @interface Model : NSObject
    12 
    13 @property (nonatomic, copy, readonly) NSString *name;
    14 
    15 @property (nonatomic, assign, readonly) NSInteger height;
    16 
    17 + (NSArray *)loadData;
    18 
    19 @end

    model.h

     1 //
     2 //  Model.m
     3 //  KVC熟悉与加强
     4 //
     5 //  Created by ma c on 16/5/16.
     6 //  Copyright © 2016年 彭盛凇. All rights reserved.
     7 //
     8 
     9 #import "Model.h"
    10 
    11 @implementation Model
    12 
    13 - (NSString *)description
    14 {
    15     return [NSString stringWithFormat:@"model.name = %@, mdoel.height = %@", _name, @(_height)];
    16 }
    17 
    18 - (void)setValue:(id)value forUndefinedKey:(NSString *)key {
    19     
    20     NSLog(@"key = %@没有找到",key);
    21     
    22 }
    23 
    24 + (NSArray *)loadData {
    25     
    26     //获取plist文件路径
    27     NSString *path = @"/Users/mac/Desktop/KVC熟悉与加强/KVC熟悉与加强/CoderPSS.plist";
    28     
    29     //获取plist文件中的数组
    30     NSArray *array = [NSArray arrayWithContentsOfFile:path];
    31     
    32     //初始化可变数组
    33     NSMutableArray *dataList = [NSMutableArray array];
    34     
    35     //使用字典遍历plist中的数组
    36     for (NSDictionary *dict in array) {
    37         
    38         //初始化model类
    39         Model *model = [[Model alloc] init];
    40         
    41         //使用KVC(setValuesForKeysWithDictionary)方法解析数据
    42         [model setValuesForKeysWithDictionary:dict];
    43         
    44         //将model类加到可变数组
    45         [dataList addObject:model];
    46     }
    47     
    48     //返回可变数组
    49     return dataList;
    50 }
    51 
    52 @end

    运行结果

  • 相关阅读:
    关于flash在html的引用 ——OBJECT EMBED
    JS的trim()方法
    JavaScript语言精粹》(JavaScript: The Good Parts) 中文版PDF
    swfobject.js 详细解说
    百度文库功能的实现
    能说明你的Javascript技术很烂的五个原因zz
    Aptana3 使用不完全指南
    js高级功能与高级需求、高级期待
    js思维导图
    AspectCore使用 属性注入FromServiceContext
  • 原文地址:https://www.cnblogs.com/PSSSCode/p/5499510.html
Copyright © 2011-2022 走看看